我有数百行不同长度的文件。我想找到包含字符串“New”的每一行,并打印前 7 个字符和最后一个字符后的第 10 个字符。
例如, cat file1.txt
1234567 New line with irrelevant info x end line
2345678 irrelevant line
3456789 New line with different irrelevant info y end line
4567890 irrelevant line
5678901 New line with yet more irrelevant info z end line
我的输出将是:
1234567 x
3456789 y
5678901 z
答案1
POSIXly:
假设这些行至少包含 10 个字符(如果不是,则未指定第二个的行为substr()
,您可以在后面添加&& length >= 10
或&& length >= 17
来/New/
跳过少于 10 或 17 个字符的行):
awk '/New/ {print substr($0, 1, 7), substr($0, length - 9, 1)}'
或者假设这些行至少包含 17 个字符(不包含的行将被跳过):
sed -n '/New/ s/^\(.\{7\}\).*\(.\).\{9\}$/\1 \2/p'
答案2
选择您喜欢的一项:
awk
解决方案:
awk '/New/{ print substr($0, 1, 7), substr($0, length-9, 1) }' file1.txt
sed
解决方案:
sed -rn '/New/ s/^(.{7}).*(.).{9}$/\1 \2/p' file1.txt
示例输出(对于两种方法):
1234567 x
3456789 y
5678901 z
答案3
gawk
这是一种完成这项工作的“残酷”解决方案,使用null
字段分隔符FS
和输出字段分隔符OFS
,这意味着输入文件的每个字符都被视为 awk 的字段。
awk '/New/{print $1,$2,$3,$4,$5,$6,$7," ",$(NF-9)}' FS="" OFS="" file1
1234567 x
3456789 y
5678901 z
更多使用 grep / sed 的解决方案将随之而来。
答案4
为了多样化,仅使用 bash 解决方案。当处理文件中的多行时,sed 和 awk 通常是更好的工具,但 bash 可以完成工作。这里的字符串切片变量扩展很方便。
while IFS= read -r line
do
# Check the line length.
# This could be whatever test defines an irrelevant line.
if [ "${#line}" -lt "25" ]
then
continue
fi
printf '%s\n' "${line:0:7} ${line: -10:1}"
done < file1.txt
输出
1234567 x
3456789 y
5678901 z