给定一个包含以下内容的文件:
1 2 3 4
5 6 7 8
a b c d
e f g h
是否有任何unix命令可用于循环移动行和列?
我正在寻找类似的话,
circular_shift -r 2 <file>
(换乘2行)给出:
a b c d
e f g h
1 2 3 4
5 6 7 8
和
circular_shift -c 2 <file>
(按2移位列)给出:
3 4 1 2
7 8 5 6
c d a b
g h e f
谢谢!
答案 0 :(得分:6)
使用awk进行行移位处理file
两次:
$ awk -v r=2 'NR==FNR && FNR>r || NR>FNR && FNR<=r' file file
a b c d
e f g h
1 2 3 4
5 6 7 8
基本上它会在第一次打印时记录NR > r
,在第二次打印时记录NR <= r
。
修改:有关记录和字段的版本:
$ awk -v r=1 -v c=1 '
NR==FNR && FNR>r || NR>FNR && FNR<=r {
j=0;
for(i=c+1;++j<=NF;i=(i<NF?i+1:1)){
printf "%s%s",$i,(i==c?ORS:OFS)
}
}
' foo foo
6 7 8 5
b c d a
f g h e
2 3 4 1
(我在参加会议时几乎未经测试......它至少在c=0
失败了)
答案 1 :(得分:4)
在gawk
circular_shift.awk
{for(i=1; i<=NF; ++i){d[NR][i]=$i}}
END{
c=c%NF; r=r%NR
for(i=1; i<=NR; ++i){
nr = i + (i>r?0:NR) - r
for(j=1; j<=NF; ++j){
nc = j + (j>c?0:NF) - c
printf d[nr][nc] (j!=NF?OFS:RS)
}
}
}
awk -vr = 2 -f circular_shift.awk file
a b c d
e f g h
1 2 3 4
5 6 7 8
awk -vc = 2 -f circular_shift.awk file
3 4 1 2
7 8 5 6
c d a b
g h e f
awk -vr = 2 -vc = 2 -f circular_shift.awk file
c d a b
g h e f
3 4 1 2
7 8 5 6
答案 2 :(得分:3)
您可以使用head
,tail
和shell:
function circular_shift() {
n=$1
file=$2
tail -n +"$((n+1))" "$file"
head -n "$n" "$file"
}
像这样调用函数:
circular_shift 2 <file>
一个限制。上述功能仅适用于n <= nlines(file)
。如果你想摆脱这个限制,你需要事先知道文件的长度并使用模运算符:
function circular_shift() {
n=$1
file=$2
len="$(wc -l "$file"|cut -d" " -f1)"
n=$((n%len))
tail -n +"$((n+1))" "$file"
head -n "$n" "$file"
}
现在尝试致电:
circular_shift 6 <file>
对于列移位,我会使用awk
:
列shift.awk
{
n = n % NF
c = 1
for(i=NF-n+1; i<=NF; i++) {
a[c++] = $i
}
for(i=1; i<NF-n+1; i++) {
a[c++] = $i
}
for(i=1; i<c; i++) {
$i = a[i]
}
}
print
将它包装在shell函数中:
function column_shift() {
n="$1"
file="$2"
awk -v n="$n" -f column-shift.awk "$file"
}
答案 3 :(得分:0)
@Vivek V K,试试: 用于将行移动到向上的数字。
awk -vcount=2 'NR>count{print;next} NR<=count{Q=Q?Q ORS $0:$0} END{print Q}' Input_file
如果要移动字段,请尝试以下操作:
awk -vcount=2 '{for(i=count+1;i<=NF;i++){Q=Q?Q FS $i:$i};for(j=1;j<=count;j++){P=P?P FS $j:$j};print Q FS P;Q=P=""}' Input_file
答案 4 :(得分:0)
awk -v C=$1 -v R=$2 '
function PrintReverse () {
if( ! R ) return
for( i=1; i>=0; i--) {
for( j=1; j<=R; j++) {
#print "DEBUG:: i: "i " j:" j " i * R + j :" i * R + j " lr:" lr
print L[ i * R + j ]
L[ i * R + j ] = ""
}
}
}
{
if( C ) {
# Reverse Column
for ( i=1; i<=NF; i+=2*C) {
for( j=0; j<C; j++) {
#print "DEBUG:: i: "i " j:" j " NF:" NF
tmp = $(i+j)
$(i+j) = $(i+j+C)
$(i+j+C) = tmp
}
}
$1=$1
}
if ( R ) {
# Line buffer
lr = ( FNR - 1 ) % ( R * 2 ) + 1
L[ lr] = $0
}
else print
}
lr >= ( R * 2) { PrintReverse() }
END { if( lr < ( R * 2 )) PrintReverse() }
' YourFile
将做你的反向行动
( C )
,( ! R )
,...以允许单一反向(仅限行或列)