如何使用bash脚本将一行中的重复模式分成多行?

时间:2013-10-13 04:11:09

标签: linux bash sed awk cut

我对bash脚本有一些问题。

我有一个字符串,它有一些像这样的重复模式。

1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 ...

每个字段由制表键分隔。

我希望它看起来像这样......

1 2 3 4
1 2 3 4
1 2 3 4
…

如何使用cut,sed,awk等bash脚本解决此问题?

我尝试过像cut -f 'seq 4, 4, 40' example.txt

这样的命令

它不起作用......

看起来很容易,但对我来说很难......

6 个答案:

答案 0 :(得分:1)

您可以像这样使用sed:

s='1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4'
p='1 2 3 4'
echo "$s"|sed "s/$p\s*/&\n/g"
1 2 3 4 
1 2 3 4 
1 2 3 4 
1 2 3 4

现场演示:http://ideone.com/P59OCJ

答案 1 :(得分:1)

如果您事先知道序列的结束编号,则可以执行以下操作:

LAST_NUMBER=4
sed -e "s/$LAST_NUMBER\t*/&\n/g" < example.txt

只需将4替换为序列中的最后一个数字

如果您不知道该号码,则必须使用以下内容进行搜索:

#!/bin/bash

declare -A CHECKED_NUMBERS
LAST_NUMBER=

while read LINE; do
    SPLIT_LINE=$(cut -d" " -f1- <<< "$LINE")

    for number in $SPLIT_LINE; do 
        if [ "${CHECKED_NUMBERS[$number]}" == "1" ]; then
            LAST_NUMBER=$number
        else
            CHECKED_NUMBERS[$number]=1
        fi
    done
done < example.txt

# do the replacement 
sed -e "s/$LAST_NUMBER\t*/&\n/g" < example.txt

答案 2 :(得分:1)

这是一个纯粹的bash解决方案:

IFS=$'\t' set -- $(<input_file)
seen=()
while [[ $1 ]]; do
  if (( ${seen[$1]} )); then # If we've seen the value before, start a new line.
    echo
    unset seen
  fi
  printf '%s ' "$1"
  seen[$1]=1
  shift
done

答案 3 :(得分:1)

awk版本

awk  '{for (i=1;i<=NF;i++) {printf "%s"(i%4?" ":"\n"),$i}}' file
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4

gnu awk版本

awk -v RS="\t" '{printf "%s"(NR%4?" ":"\n"),$0}' file
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4

答案 4 :(得分:1)

xargs可能会有所帮助:

kent$  echo "1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4"|xargs -n4
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4

答案 5 :(得分:1)

这可能对您有用:

printf "%s\t%s\t%s\t%s\n" $string

或者您希望字段空格分隔:

printf "%s %s %s %s\n" $string