Kam*_*Cuk 6 bash shell gnu-coreutils
我有一个这样的示例input.txt
文件:
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat
nulla pariatur. Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
Run Code Online (Sandbox Code Playgroud)
现在,我可以轻松地grep输入一个单词,并获取它的字节偏移量:
$ grep -ob incididunt /dev/null input.txt
input.txt:80:incididunt
Run Code Online (Sandbox Code Playgroud)
可悲的是,有关行内容的信息和有关所搜索单词的信息都丢失了。我只知道文件名和80
字节偏移量。我想打印包含该文件内部字节偏移量的整行。
因此,理想情况下,将得到一个script.sh
带有两个参数(文件名和字节偏移)的a,输出搜索到的行:
$ ./script.sh input.txt 80
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
Run Code Online (Sandbox Code Playgroud)
另一个例子:
对于file = input.txt和byte offset = 130,输出应为:
enim ad minim veniam, quis nostrud exercitation ullamco laboris
Run Code Online (Sandbox Code Playgroud)
对于file = input.txt和195到253之间的任何字节偏移,输出应为:
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
Run Code Online (Sandbox Code Playgroud)
对于file = input.txt和byte offset = 400,输出应为:
sunt in culpa qui officia deserunt mollit anim id est laborum.
Run Code Online (Sandbox Code Playgroud)
我试过了:
我可以使用gnu sed从字节偏移量开始打印直到行尾,但是会漏掉eiusmod tempor
一部分。我想不出如何在文件中“返回”,从换行符中取出该部分直到该字节偏移的想法。
$ sed -z 's/.\{80\}\([^\n]*\).*/\1\n/' input.txt
incididunt ut labore et dolore magna aliqua. Ut
Run Code Online (Sandbox Code Playgroud)
我可以逐个字符地阅读,记住最后一个换行符,并从最后一个换行符开始打印直到下一个换行符。这将对shell无效read
,因为它省略了换行符。我想我可以使用它来工作dd
,但是肯定有一个更简单的解决方案。
set -- inpux.txt 80
exec 10<"$1"
pos=0
lastnewlinepos=0
for ((i=0;i<"$2";++i)); do
IFS= read -r -u 10 -N 1 c
pos=$((pos+1))
# this will not work..., read omits newlines
if [ "$c" = $'\n' ]; then
lastnewlinepost="$pos"
fi
done
# as I know the last newline before the offset, it's ok to use this now
sed -z 's/.\{'"$lastnewlinepos"'\}\([^\n]*\).*/\1\n/' "$1"
Run Code Online (Sandbox Code Playgroud)
如何使用bash和* nix专用工具打印包含文件中字节偏移量的整行?
当变量达到字节偏移量时,在变量中保持到目前为止已读取的字节数,然后打印当前行并退出。
$ awk '{read+=1+length} read>=80{print;exit}' input.txt
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
$ awk '{read+=1+length} read>=130{print;exit}' input.txt
enim ad minim veniam, quis nostrud exercitation ullamco laboris
Run Code Online (Sandbox Code Playgroud)
length
是当前行的长度,我们需要向其添加1,因为awk会修剪行中的记录分隔符(\n
默认情况下)。
请注意,这length
将对字符进行计数,根据语言环境的不同,最多可能需要占用六个字节。要使其计数字节,您需要在运行awk时将环境变量设置LC_ALL
为C
,例如:
LC_ALL=C awk '{read+=1+length} read>=130{print;exit}' input.txt
Run Code Online (Sandbox Code Playgroud)