我的脚本中有一个字符串变量,由ls -l </ p>中的9个权限字符组成
例如:
rwxr-XR -
我想操纵它,使它显示如下:
r w x r - x r - -
IE每隔三个字符分隔标签,其他所有字符用空格分隔。我最接近的是使用printf
printf "%c %c %c\t%c %c %c\t%c %c %c\t/\n" "$output"{1..9}
这仅打印第一个字符,但格式正确
我确定可以使用&#34; sed&#34;我无法想到
有什么建议吗?
答案 0 :(得分:5)
使用Posix指定的实用程序fold
和paste
,将字符串拆分为单个字符,然后交错显示一系列分隔符:
fold -w1 <<<"$str" | paste -sd' \t'
答案 1 :(得分:3)
$ sed -r 's/(.)(.)(.)/\1 \2 \3\t/g' <<< "$output"
r w x r - x r - -
可悲的是,这会在输出中留下一个尾随标签。如果您不想要,请使用:
$ sed -r 's/(.)(.)(.)/\1 \2 \3\t/g; s/\t$//' <<< "$str"
r w x r - x r - -
答案 2 :(得分:1)
为什么你需要解析它们? U可以通过复制所需元素访问字符串的每个元素。它非常简单,没有任何实用性,例如:
DATA="rwxr-xr--"
while [ $i -lt ${#DATA} ]; do
echo ${DATA:$i:1}
i=$(( i+1 ))
done
答案 3 :(得分:1)
使用awk
:
$ echo "rwxr-xr--" | awk '{gsub(/./,"& ");gsub(/. . . /,"&\t")}1'
r w x r - x r - -
答案 4 :(得分:0)
> echo "rwxr-xr--" | sed 's/\(.\{3,3\}\)/\1\t/g;s/\([^\t]\)/\1 /g;s/\s*$//g'
r w x r - x r - -
(显然我没有太多考虑我的sed
命令.John Kugelman的版本显然更清晰,更简洁。)
编辑:我完全同意三联的评论。不要浪费你的时间来解析ls
输出。我做了很长时间之后我发现你可以得到你想要的东西(只你想要的东西)更多更容易使用stat
。例如:
> stat -c %a foo.bar # Equivalent to stat --format %a
0754
-c %a
告诉stat
以八进制输出指定文件的访问权限。它打印出 all ,因此无需像ls foo.bar | awk '{print $1}'
等那样做古怪的东西。
例如,你可以做类似的事情:
GROUP_READ_PERMS=040
perms=$(stat -c %a foo.bar)
if (( (perms & GROUP_READ_PERMS) != 0 )); then
... # Do some stuff
fi
当然,他正在解析像“rwxr-xr - ”
这样的字符串答案 5 :(得分:0)
设置awk -F ''
允许每个字符都有界限,然后你需要遍历并打印每个字段。
示例:
ls -l | sed -n 2p | awk -F '' '{for(i=1;i<=NF;i++){printf " %s ",$i;}}'; echo ""
这部分似乎就是你问题的答案:
awk -F '' '{for(i=1;i<=NF;i++){printf " %s ",$i;}}'
我知道,这并不能提供你想要的三元组。嗯...
答案 6 :(得分:0)
sed 's/.../& /2g;s/./& /g' YourFile
在2个简单的步骤
答案 7 :(得分:0)
一个版本,其中包括用于短字符串的纯bash
版本和用于较长字符串的sed
版本,并保留换行符(也在换行符后添加空格)
if [ "${OS-}" = "Windows_NT" ]; then
threshold=1000
else
threshold=100
fi
function escape()
{
local out=''
local -i i=0
local str="${1}"
if [ "${#str}" -gt "${threshold}" ]; then
# Faster after sed is started
sed '# Read all lines into one buffer
:combine
$bdone
N
bcombine
:done
s/./& /g' <<< "${str}"
else
# Slower, but no process to load, so faster for short strings. On windows
# this can be a big deal
while (( i < ${#str} )); do
out+="${str:$i:1} "
i+=1
done
echo "$out"
fi
}
sed的解释。 “如果这是最后一行,则跳转到:done
,否则将Next附加到缓冲区中并跳转到:combine
。:done
之后是一个简单的sed替换表达式。整个字符串(换行符和所有)放在一个缓冲区中,因此替换也可以在换行符上使用(在某些awk -F
示例中丢失了)
Plus 这是Linux,Mac和Windows兼容的Git。