Bash 如何逐行使用sed?
我知道我做错了什么,但我不知道是什么Bash 如何逐行使用sed?,bash,ubuntu,awk,sed,Bash,Ubuntu,Awk,Sed,我知道我做错了什么,但我不知道是什么 #!/bin/bash while IFS='' read -r line do new=$(git log -1 --pretty="format:%ct" $line) sed "s|$line: .*|: $new|" file.yml done < <(awk 'NR>1{sub(/:.*/,"");print $1}' file.yml) 那么,我想做什么 我有file.yml,
#!/bin/bash
while IFS='' read -r line
do
new=$(git log -1 --pretty="format:%ct" $line)
sed "s|$line: .*|: $new|" file.yml
done < <(awk 'NR>1{sub(/:.*/,"");print $1}' file.yml)
那么,我想做什么
我有file.yml
,带有一些文件源和UNIX时间戳(上次修改日期)。我想用git log
检查每个文件。从git log
我收到新的时间戳修改日期,我需要用新日期替换旧日期
我所期望的是:
catalog/view/css/animate.css/3.1.1/animate.min.css: 1484135987
catalog/view/fonts/cinzel/fonts.css: 1484136578
我得到了什么(因此我认为sed
无法逐行工作):
sed
输出文件内容,不修改文件
$line:.*
将匹配整行,因此它将删除该行,并将整行替换为:$new
如果您有GNU sed,您可以使用-i
sed参数就地修改文件:
sed -i "s|$line: .*|$line: $new|" file.yml
或者更好:
sed -i "s|\($line: \).*|\1$new|" file.yml
但是你不能同时读写同一个文件
另外,sub(/:.*/,“”)
看起来很奇怪-只要用:
作为分隔符阅读,这就是IFS的用途<代码>当IFS=:read-r行忽略其余部分;做已完成新建_file.yml
mv new_file.yml file.yml
如果确实要进行就地编辑,请首先缓存文件,以便不会同时读取和写入同一文件
readarray -t files < <(awk 'NR>1{sub(/:.*/,"");print $1}' file.yml)
for line in "${files[@]}"; do
new=$(git log -1 --pretty="format:%ct" "$line")
sed -i "s|\($line: \).*|\1$new|" file.yml
done
readarray-t文件
sed 's/\(^.*\): \(.*\)/echo \1: $(code_to_get_new_timestamp)/e' file.yml
<代码>:$$行:*$:“< /代码>:您正在输出文件内容并替换整个行。好的,有什么建议?建议:1)将示例简化为两个文件(在该大的输出块中有太多的东西);2)考虑建立一个新的时间戳文件,当完成时只覆盖原始文件。(或者将原始文件归档,并将新文件重命名为file.yml
);至于从file.yml
中提取文件名,awk-F:“{print$1}”
或cut-d:”-f1
更易于阅读/理解,谢谢。主要问题是,像在循环中一样更改每个文件中的时间戳。
sed -i "s|\($line: \).*|\1$new|" file.yml
{
IFS= read -r preserve_first_line
printf "%s\n" "$preserve_first_line"
while IFS=':' read -r line _; do
new=$(git log -1 --pretty="format:%ct" "$line")
echo "$line: $new"
done
} < file.yml > new_file.yml
mv new_file.yml file.yml
readarray -t files < <(awk 'NR>1{sub(/:.*/,"");print $1}' file.yml)
for line in "${files[@]}"; do
new=$(git log -1 --pretty="format:%ct" "$line")
sed -i "s|\($line: \).*|\1$new|" file.yml
done
sed 's/\(^.*\): \(.*\)/echo \1: $(code_to_get_new_timestamp)/e' file.yml