在字符串中的每个字符后添加空格

时间:2014-03-12 20:43:40

标签: string bash sed scripting formatting

我的脚本中有一个字符串变量,由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;我无法想到

有什么建议吗?

8 个答案:

答案 0 :(得分:5)

使用Posix指定的实用程序foldpaste,将字符串拆分为单个字符,然后交错显示一系列分隔符:

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。

相关问题