给定文件' a.txt '中的每一行都包含另一个唯一文件的目录/路径。假设我们要逐行解析“ a.txt ”,以字符串格式提取路径,然后使用诸如vim之类的工具在此路径下处理文件,依此类推。
经过这个线程-Read a file line by line assigning the value to a variable之后,我在bash上写了以下脚本,说“ open-file.sh ”(是我的新手)
#!/bin/bash
while IFS='' read -r line || [[ -n "$line" ]]; do
vim -c ":q" -cq $line # Just open the file and close it using :q
done < "$1"
然后我们将上述脚本运行为-
./open-file.sh a.txt
问题是,尽管$ line正确指定了新文件的路径,但是当vim打开文件时,vim继续以命令的形式接收' a.txt '中包含的文本。如何编写一个脚本,在这里我可以正确地从' a.txt '获取路径,使用vim打开它,然后继续解析' a.txt 中的其余行>'?
答案 0 :(得分:2)
替换:
vim -c ":q" -cq $line
使用:
vim -c ":q" -cq "$line" </dev/tty
重定向</dev/tty
告诉vim
从终端获取其标准输入。否则,vim
的标准输入为"$1"
。
此外,优良作法是将$line
放在双引号中以防止分词等。
最后,虽然vim
非常适合进行交互工作,但是如果最终目标是对每个文件进行全自动处理,则您可能需要考虑使用sed
或awk
之类的工具。
答案 1 :(得分:0)
尽管我不确定您的最终目标,但是此shell命令将在2
3
4
5
11
12
13
14
15
16
17
18
19
中每行执行一次vim:
a.txt
正如对Read a file line by line assigning the value to a variable的评论中所述,您遇到的问题是由于vim是一个交互式程序,因此继续从xargs -o -n1 vim -c ':q' < a.txt
读取输入。
答案 2 :(得分:0)
问题出在您基于脚本的答案下的already mentioned in a comment。
vim
正在消耗stdin
,它由done < $1
赋予循环。在下面的示例中,我们可以观察到相同的行为:
$ while read i; do cat; done < <(seq 3)
2
3
<(seq 3)
用三行1
,2
和3
模拟文件。而不是三个静默迭代,我们只能得到一个迭代,并且输出为2
和3
。
stdin
不仅在循环头传递给read
,而且在循环体传递给cat
。因此,read
读取一行,进入循环,cat
读取所有剩余的行,stdin
为空,read
不再需要读取,循环退出。>
您可以通过将某些内容重定向到vim
来解决问题,但是还有更好的方法。您根本不需要循环:
< "$1" xargs -d\\n -n1 vim -c :q -cq
xargs
将对vim
给定的文件中的每一行执行一次$1
。