sed command in dry run

感情迁移 提交于 2019-12-20 09:56:10

问题


I am not able to find out if and how it is possible to make a dry run with sed.

So i have this command:

find ./ -type f | xargs sed -i 's/string1/string2/g'

But before I really substitute in all the files, i want to check what it WOULD substitute. Copying the whole directory structure to check is no option!

Thanks for any feedback (negative or positive :) )


回答1:


Remove the -i and pipe it to less to paginate though the results. Alternatively, you can redirect the whole thing to one large file by removing the -i and appending > dryrun.out

I should note that this script of yours will fail miserably with files that contain spaces in their name or other nefarious characters like newlines or whatnot. A better way to do it would be:

while IFS= read -r -d $'\0' file; do
  sed -i 's/string1/string2/g' "$file"
done < <(find ./ -type f -print0)



回答2:


I would prefer to use the p-option:

find ./ -type f | xargs sed 's/string1/string2/gp'

Could be combined with the --quiet parameter for less verbose output:

find ./ -type f | xargs sed --quiet 's/string1/string2/gp'

From man sed:

p:

Print the current pattern space.

--quiet:

suppress automatic printing of pattern space




回答3:


I know this is a very old thread and the OP doesn't really need this answer, but I came here looking for a dry run mode myself, so thought of adding the below piece of advice for anyone coming here in future. What I wanted to do was to avoid stomping the backup file unless there is something really changing. If you blindly run sed using the -i option with backup suffix, existing backup file gets overwritten, even when there is nothing substituted.

The way I ended up doing is to pipe sed output to diff and see if anything changed and then rerun sed with in-place update option, something like this:

if ! sed -e 's/string1/string2/g' $fpath | diff -q $fpath - > /dev/null 2>&1; then
    sed -i.bak -e 's/string1/string2/g' $fpath
fi

As per OP's question, if the requirement is to just see what would change, then instead of running the in-pace sed, you could do the diff again with some informative messages:

if ! sed -e 's/string1/string2/g' $fpath | diff -q $fpath - > /dev/null 2>&1; then
    echo "File $fpath will change with the below diff:"
    sed -e 's/string1/string2/g' $fpath | diff $fpath -
fi

You could also capture the output in a variable to avoid doing it twice:

diff=$(sed -e 's/string1/string2/g' $fpath | diff $fpath -)
if [[ $? -ne 0 ]]; then
    echo "File $fpath will change with the below diff:"
    echo "$diff"
fi


来源:https://stackoverflow.com/questions/4513623/sed-command-in-dry-run

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!