使用 Bash 脚本循环删除多个文件的第一行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20030506/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Loop for deleting first line of Multiple Files using Bash Script
提问by Marko
Just new to Bash scripting and programming in general. I would like to automate the deletion of the first line of multiple .data files in a directory. My script is as follows:
刚开始接触 Bash 脚本和编程。我想自动删除目录中多个 .data 文件的第一行。我的脚本如下:
#!/bin/bash
for f in *.data ;
do tail -n +2 $f | echo "processing $f";
done
I get the echo message but when I cat the file nothing has changed. Any ideas?
我收到回显消息,但是当我发现文件时,没有任何变化。有任何想法吗?
Thanks in advance
提前致谢
采纳答案by pfnuesel
You are not changing the file itself. By using tail
you simply read the file and print parts of it to stdout
(the terminal), you have to redirect that output to a temporary file and then overwrite the original file with the temporary one.
您没有更改文件本身。通过使用tail
您只需读取文件并将其部分打印到stdout
(终端),您必须将该输出重定向到一个临时文件,然后用临时文件覆盖原始文件。
#!/usr/bin/env bash
for f in *.data; do
tail -n +2 "$f" > "${f}".tmp && mv "${f}".tmp "$f"
echo "Processing $f"
done
Moreover it's not clear what you'd like to achieve with the echo
command. Why do you use a pipe (|
) there?
此外,还不清楚您想使用该echo
命令实现什么目标。为什么要在|
那里使用管道 ( )?
sedwill give you an easier way to achieve this. See devnull's answer.
sed将为您提供一种更简单的方法来实现这一目标。请参阅 devnull 的答案。
回答by devnull
I get the echo message but when I cat the file nothing has changed.
我收到回显消息,但是当我发现文件时,没有任何变化。
Because simply tail
ing wouldn't change the file.
因为简单的tail
ing 不会改变文件。
You could use sed
to modify the files in-place with the first line excluded. Saying
您可以使用sed
排除第一行的就地修改文件。说
sed -i '1d' *.data
would delete the first line from all .data
files.
将从所有.data
文件中删除第一行。
EDIT: BSD sed
(on OSX) would expect an argument to -i
, so you can either specify an extension to backup older files, or to edit the files in-place, say:
编辑:BSD sed
(在 OSX 上)需要一个参数-i
,因此您可以指定扩展名来备份旧文件,或者就地编辑文件,例如:
sed -i '' '1d' *.data
回答by John Zwinck
I'd do it this way:
我会这样做:
#!/usr/bin/env bash
set -eu
for f in *.data; do
echo "processing $f"
tail -n +2 "$f" | sponge "$f"
done
If you don't have sponge
you can get it in the moreutils
package.
如果你没有,sponge
你可以把它放在moreutils
包里。
The quotes around the filename are important--they will make it work with filenames containing spaces. And the env
thing at the top is so that people can set which Bash interpreter they want to use via their PATH, in case someone has a non-default one. The set -eu
makes Bash exit if an error occurs, which is usually safer.
文件名周围的引号很重要——它们将使其适用于包含空格的文件名。而env
在顶部的事情是让人们可以将其击解释,他们希望通过他们的路径使用,万一有人有一个非默认之一。该set -eu
如果发生错误,通常是安全的,使击出。
回答by gniourf_gniourf
ed
is the standard editor:
ed
是标准编辑器:
shopt -s nullglob
for f in *.data; do
echo "Processing file \`$f'"
ed -s -- "$f" < <( printf '%s\n' "1d" "wq" )
done
The shopt -s nullglob
is here just because you should always use this when using globs, especially in a script: it will make globs expand to nothing if there are no matches; you don't want to run commands with uncontrolled arguments.
之所以shopt -s nullglob
在这里只是因为在使用 glob 时应该始终使用它,尤其是在脚本中:如果没有匹配项,它将使 glob 扩展为空;您不想运行带有不受控制的参数的命令。
Next, we loop on all your files, and use ed
with the commands:
接下来,我们循环您的所有文件,并使用ed
以下命令:
1
: go to first lined
: delete that linewq
: write and quit
1
: 转到第一行d
: 删除那行wq
: 写入并退出
Options for ed
:
选项ed
:
-s
: tellsed
to shut up! we don't wanted
to print its junk on our screen.--
: end of options: this will make your script much more robust, in case a file name starts with a hypen: in this case, the hyphen will confuseed
trying to process it as an option. With--
,ed
knows that there are no more options after that and will happily process any files, even those starting with a hyphen.
-s
: 告诉ed
你闭嘴!我们不想ed
在我们的屏幕上打印它的垃圾。--
: 选项结束:这将使您的脚本更加健壮,以防文件名以连字符开头:在这种情况下,连字符会混淆ed
尝试将其作为选项处理。使用--
,ed
知道此后没有更多选项,并且会很乐意处理任何文件,即使是那些以连字符开头的文件。