我正在尝试在Unix中交换文本文件中的第一行和最后一行。 文件内容为:
line1
line2
line3
line4
line5
line6
I want like this:
line6
line2
line3
line4
line5
line1
我正在使用
sed -n -e '1 s/^.*$/$p' file
,但它并没有起作用。编辑2: 根据Ed先生的评论,在此添加这个解决方案,即使第二行为空也将起作用。
awk 'NR==1{first=$0;next} NR>2{val=val prev ORS} {prev=$0} END{print prev ORS val first} Input_file
编辑:如果您要想只交换第一行和最后一行,下面的方法可能会有帮助(假设您的输入文件与示例相同)。awk 'FNR==1{first=$0;next} {val=(val?val ORS prev:prev?$0:"")} {prev=$0} END{print $0 ORS val ORS first}' Input_file
解释:
awk '
FNR==1{ ##Checking if line is first line then do following.
first=$0; ##Creating varable first whose value is current line value.
next ##next will skip all further statements from here.
}
{
val=(val?val ORS prev:prev?$0:"") ##Creating variable named val here whoe value is concatenating to its own value with variable prev value.
}
{
prev=$0 ##Creating variable prev whose value will be current value of line but will become previous value for next line.
}
END{
print $0 ORS val ORS first ##Printing current line ORS val ORS and first here.
}' Input_file ##Mentioning Input_file name here.
请您尝试以下方法,如果有帮助请告知我。
awk -v from=1 -v to=6 'FNR==from{source=$0;next} FNR==to{target=$0;next} {val=val?val ORS $0:$0} END{print target ORS val ORS source}' Input_file
awk 'NR==1{first=$0;next} NR>2{val=val prev ORS} {prev=$0} END{print prev ORS val first}' file
。 - Ed Morton在sed中,您需要进行两次处理;使用ed可能更有意义。然后我们只需要两个move命令-将最后一行移动到第1行之后,然后将第一行移动到末尾:
$m1
1m$
#!/bin/bash
set -euo pipefail
# Create our input file
file=$(mktemp)
trap 'rm "$file"' EXIT
cat >"$file" <<END
line1
line2
line3
line4
line5
line6
END
echo Before:
cat "$file"
echo
# Make the change
ed -s "$file" <<<$'$m1\n1m$\nwq'
# Show the result
echo After:
cat "$file"
如果你需要编写不同的输出文件,当然可以像往常一样向wq
命令添加文件名参数。
sed 'H;$!d;x;s/\n\([^\n]*\)\(\n.*\n\)\(.*\)/\3\2\1/' file
将整个文件复制到保留空间(HS)中,并在最后一行之后,切换到HS,将文件分成第一行、中间和最后一行,并替换第一行和最后一行。
另一种两遍的解决方案:
sed -n '1s/.*/$c&/p;$s/.*/1c&/p' file | sed -f - file
cat <(tail -1 file) <(sed '1d;$d' file) <(head -1 file)
另一个sed解决方案:
sed -E '1h;1d;:a;N;$!ba;s/(.*)\n(.*)/\2\n\1/;G' file
如果需要混合使用一行代码,包括 head
、tail
和 sed
:
$ FIRST=$(head -1 file.txt) LAST=$(tail -1 file.txt) \
sed "1 s/^.*$/${LAST}/" file.txt | sed "$ s/^.*$/${FIRST}/"
对于非常大的文件,您可能会对双重传递感兴趣:
awk '(NR!=FNR){print (FNR==1 ? t : (FNR==c ? h : $0) ); next }
(NR==1){h=$0}{t=$0;c=NR}' file file
first="$(head -n 1 file1)"; last="$(tail -n 1 file1)"; echo -e $"$last" "\n$(cat file1 | tail -n +2 | head -n -1)" $"\n$first" > file2
- Wiktor Stribiżew