我的输入文件格式为:
0 1 0 0 0 1 1 0 0 0 / 1 0 / 1 0 / 1
0 1 0 3/4 1 0 0 1/4 0 0 -1 1/2
0 -1 0 1/4 -1 0 0 3/4 0 0 1 1/2
我想重新排列其中包含分数的行的顺序。目前我有:
#!bin/bash
filename="input.txt"
while ((i++)); read -r line; do
re='[0-9][/][0-9]';
if [[ $line =~ $re ]]
then
echo $line
fi
done < "$filename"
将回显第二和第三行。是否有一个awk或sed命令我可以使用这两行来改变它们的顺序(将第一行保留为原样)
$1,$2,$3,$5,$6,$7,$9,$10,$11,$4,$8,$12
这将使我的文件现在看起来像
0 1 0 0 0 1 1 0 0 0 / 1 0 / 1 0 / 1
0 1 0 1 0 0 0 0 -1 3/4 1/4 1/2
0 -1 0 -1 0 0 0 0 1 1/4 3/4 1/2
答案 0 :(得分:3)
最好使用awk
完成:
awk -v OFS='\t' '/[0-9]\/[0-9]/{print $1,$2,$3,$5,$6,$7,$9,$10,$11,$4,$8,$12; next} 1' file
0 1 0 0 0 1 1 0 0 0 / 1 0 / 1 0 / 1
0 1 0 1 0 0 0 0 -1 3/4 1/4 1/2
0 -1 0 -1 0 0 0 0 1 1/4 3/4 1/2
答案 1 :(得分:0)
@anubhava是比我更好的解决方案。自从我写了其他代码之后,请注意。
#!/bin/bash
filename="input.txt"
awk '
{
for (i=1; i <= NF; i++)
if ( $(i+1) == "/" || $i == "/" || $(i-1) == "/") {
printf "MM%sMM",$i" "$(i+1)" "$(i+2)
i = i+2
} else if ( match ($i, /^[[:digit:]]\/[[:digit:]]/) ) {
printf "MM%sMM",$i
} else {
printf "MM%sMM",$i
}
printf "\n"
}' $filename | sed -e 's/MMMM/MM/g;s/^MM//;s/MM/\t/g'
答案 2 :(得分:0)
你可以用awk轻松做到这一点,但我认为定义游戏规则很重要。 根据以下假设:
a/b
或a / b
或a/ b
考虑到这一点,您可以使用以下awk代码
awk 'BEGIN{format="%4s%6s%6s%6s%6s%6s%6s%6s%6s%7s%7s%7s\n"}
{ gsub(/[[:blank:]]*\/[[:blank:]]*/,"/",$0); $0=$0 }
($4 ~ /\//) || ($8 ~ /\//) {
$12=$4" "$8" "$12
$4=""; $8=""
$0=$0
}
{ printf format,$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12 }
' file.txt
执行以下操作:
将所有" / "
或其中的任何变体替换为/
$0 = $0
重新定义字段,即前两行中的字段
将从18个字段移至12
如果分数(即/
)出现在字段4或8中,则重新定义字段12,删除字段4和8并再次执行$0=$0
。
以正确的格式打印。
注意:在上面的例子中,分数具有不同的输出(无空格)
以上将给出以下输出:
0 1 0 0 0 1 1 0 0 0/1 0/1 0/1
0 1 0 1 0 0 0 0 -1 3/4 1/4 1/2
0 -1 0 -1 0 0 0 0 1 1/4 3/4 1/2
如果您不想在第一行更改分数,那么您可以像这样轻松地完成
awk 'BEGIN{format="%4s%6s%6s%6s%6s%6s%6s%6s%6s%7s%7s%7s\n"}
(NF>12) { print; next }
{
$12=$4" "$8" "$12
$4=""; $8=""
$0=$0
printf format,$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12
}
' file.txt
这里假设,
如果一行有超过12个字段,只需打印
否则,将列洗牌
然而,这不太稳健,因为一切都取决于分数在第4,第8和第12列中的输入方式。即他们必须键入没有空格。输出如下:
0 1 0 0 0 1 1 0 0 0 / 1 0 / 1 0 / 1
0 1 0 1 0 0 0 0 -1 3/4 1/4 1/2
0 -1 0 -1 0 0 0 0 1 1/4 3/4 1/2