查找并替换脚本(困难问题...需要帮助!)

发布于 2024-12-10 12:44:11 字数 2050 浏览 0 评论 0原文

我在 zsh 中编写了一个函数,用于查找特定数字并将其替换为关键字,稍后我将在更大的脚本中使用该关键字。这是我得到的:

function replace_metal() {
for file in "$@"; do
    [ -f "$file" ] && mv $file $file.old

    # replace metal
    awk '/^28\s/ { gsub(/28\s/, "METAL") }; { print }' $file.old > $file

    # remove temporary files
    rm -f $file.old
done
}

awk 部分当我在命令行上运行它时工作正常,但在脚本中,它无法解析文件并用关键字替换数字。我不知道为什么会失败。我编写了一个类似的函数,可以毫无问题地工作

function fix_filename() {
for file in "$@"; do
    [ -f "$file" ] && mv $file $file.old

    # fix filename
    awk '{ gsub(/myFileName/,FILENAME); print }' $file.old > $file.tmp

    # clean up filename
    awk '{ gsub(/.gjf.old/,""); print }' $file.tmp > $file

    # remove temporary files
    rm -f $file.old $file.tmp
done
}

我特别困惑为什么 awk 不能在 Replace_metal 函数中工作,但可以在命令行上工作。如果有人能解释这一点,我将非常感激。

这是我要运行此脚本的文件的示例部分。它们是我使用的分子几何程序的笛卡尔坐标。

6 4.387152 -0.132561 1.145384
6 4.435130 0.035315 -0.261758
6 3.241800 0.069735 -1.002575
7 2.023205 -0.053248 -0.382329
6 1.948032 -0.217668 0.977856
6 3.120408 -0.260395 1.759133
8 0.936529 -0.001059 -1.144164
28 -0.810634 -0.374713 -0.376819
7 -1.066408 1.593331 -0.221421
6 -2.101594 2.162030 0.386527
6 -3.220999 1.475281 0.925467
7 -2.581803 -0.796964 0.180331
6 -3.412540 0.082878 0.747753
6 -0.299269 -2.264241 -0.449077
1 5.304344 -0.163663 1.737743
1 5.382399 0.136858 -0.794636
1 3.185977 0.187888 -2.085134
1 0.932373 -0.311671 1.366224
1 3.017555 -0.393258 2.837678
1 -2.114644 3.263364 0.463786
1 -4.007715 2.050042 1.415626
1 -4.379471 -0.313239 1.099097
1 -0.572811 -2.828718 0.461055
1 0.789786 -2.379489 -0.603095
1 -0.795666 -2.747919 -1.311858
6 -3.146815 -2.155894 0.046938
1 -2.990568 -2.540510 -0.972499
1 -2.672661 -2.865421 0.746200
1 -4.233217 -2.149944 0.247135
6 -0.086130 2.536630 -0.792152
1 0.886270 2.480474 -0.265799
1 0.102603 2.306402 -1.853394
1 -0.445050 3.580750 -0.720938

第一列中的项目是唯一可以更改的内容。其他三列中的项目不应更改。

感谢您的帮助!

I've written a function in zsh to find and replace a specific number with a keyword that I'll use later on in a larger script. Here's what I've got:

function replace_metal() {
for file in "$@"; do
    [ -f "$file" ] && mv $file $file.old

    # replace metal
    awk '/^28\s/ { gsub(/28\s/, "METAL") }; { print }' $file.old > $file

    # remove temporary files
    rm -f $file.old
done
}

The awk portion works fine when I run it on the command line but while in the script, it fails to parse the file and replace the number with the keyword. I'm not sure why it fails. I've written a function that is similar that works without any trouble:

function fix_filename() {
for file in "$@"; do
    [ -f "$file" ] && mv $file $file.old

    # fix filename
    awk '{ gsub(/myFileName/,FILENAME); print }' $file.old > $file.tmp

    # clean up filename
    awk '{ gsub(/.gjf.old/,""); print }' $file.tmp > $file

    # remove temporary files
    rm -f $file.old $file.tmp
done
}

I'm especially confused as to why awk won't work in the replace_metal function but will on the command line. If anyone can explain that, I'd really appreciate it.

Here's an example portion of a file that I'd run this script on. They are cartesian coordinates for a molecular geometry program I use.

6 4.387152 -0.132561 1.145384
6 4.435130 0.035315 -0.261758
6 3.241800 0.069735 -1.002575
7 2.023205 -0.053248 -0.382329
6 1.948032 -0.217668 0.977856
6 3.120408 -0.260395 1.759133
8 0.936529 -0.001059 -1.144164
28 -0.810634 -0.374713 -0.376819
7 -1.066408 1.593331 -0.221421
6 -2.101594 2.162030 0.386527
6 -3.220999 1.475281 0.925467
7 -2.581803 -0.796964 0.180331
6 -3.412540 0.082878 0.747753
6 -0.299269 -2.264241 -0.449077
1 5.304344 -0.163663 1.737743
1 5.382399 0.136858 -0.794636
1 3.185977 0.187888 -2.085134
1 0.932373 -0.311671 1.366224
1 3.017555 -0.393258 2.837678
1 -2.114644 3.263364 0.463786
1 -4.007715 2.050042 1.415626
1 -4.379471 -0.313239 1.099097
1 -0.572811 -2.828718 0.461055
1 0.789786 -2.379489 -0.603095
1 -0.795666 -2.747919 -1.311858
6 -3.146815 -2.155894 0.046938
1 -2.990568 -2.540510 -0.972499
1 -2.672661 -2.865421 0.746200
1 -4.233217 -2.149944 0.247135
6 -0.086130 2.536630 -0.792152
1 0.886270 2.480474 -0.265799
1 0.102603 2.306402 -1.853394
1 -0.445050 3.580750 -0.720938

Items in the first column are the only things that can be changed. Items in the other three columns should not ever change.

Thanks for your help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你列表最软的妹 2024-12-17 12:44:11

问题是“\”字符的转义。尝试使用“\\s”甚至“\\\\s”。如果不直接运行脚本,“\”字符将被评估两次:首先由 shell 评估,然后由 awk 评估。无论如何,你的解决方案太复杂了。

尝试:

sed -i "s/^28 /METAL/" file

sed -i 表示就地替换,因此您不必将文件“file”复制到“file.old”,然后再次返回“file”。

Zsh 有一个内置函数来转义字符串:

f="to be escaped"
print ${(q)f}

HTH Chris

the problem is the escaping of the "\"-character. Experiment with "\\s" or even "\\\\s". If you don't run the script directly, the "\"-character is evaluated two times: at first by the shell and then by awk. Anyway, you solution is way too complicated.

Try:

sed -i "s/^28 /METAL/" file

sed -i means substitute in place, so you don't have to copy the file "file" to "file.old" and then back again to "file".

Zsh has a built-in function to escape strings:

f="to be escaped"
print ${(q)f}

HTH Chris

猫性小仙女 2024-12-17 12:44:11

如果你无法获胜并且引用地狱让你发疯(并且你知道有一个空格而不是制表符),只需作弊:

awk '/^28 / { gsub(/^28 /, "METAL ") }; { print }' $file

...或者使用 [[:space:]] 而不是\s,看来 GNU awk 不理解 \s。对我来说,即使是简单的也

[0 1047 19:39:10] ~/temp/stack % gawk '/^28\s/ { gsub(/28\s/, "METAL") }; { print }' data

无法取代。 (另外,如果空格是分隔第 1 列和第 2 列的唯一因素,请不要替换掉空格:替换为 "METAL " 或仅替换 /^28/

If you can't win and quoting hell drives you mad (and you know there's a space and not a tab), just cheat:

awk '/^28 / { gsub(/^28 /, "METAL ") }; { print }' $file

... or else use [[:space:]] instead of \s, it appears GNU awk doesn't understand \s. For me, even plain

[0 1047 19:39:10] ~/temp/stack % gawk '/^28\s/ { gsub(/28\s/, "METAL") }; { print }' data

fails to replace. (Also, don't replace your space away if it's the only thing separating columns 1 and 2: replace with "METAL " or replace just /^28/.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文