天道酬勤,学无止境

bash

sed 替换双引号内的内容(sed replace content within double quotes)

问题 我需要使用 sed 从 shell 脚本替换 xml 文件中的 versionName。 <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.example.sed" android:versionCode="1" android:versionName="UNKNOWN VERSION NAME"> 我已经搜索了包含 versionName 的行,但是如何告诉 sed 替换 versionName 之后直接出现的双引号内的所有内容? sed -i .old '/versionName/ s/WHAT TO WRITE?/NEW VERSION NAME/' AndroidManifest.xml 回答1 替换not-" ,像这样: sed -i .old '/android:versionName/ s/="[^"][^"]*"/="NEW VERSION NAME"/' AndroidManifest.xml 回答2 考虑到xml的性质和版本号,使用更简单的命令其实是很安全的: sed -i '/versionName/s/".*"/"NEW VERSION NAME"

2021-11-29 18:56:59    分类:技术分享    regex   bash   sed

相当于 Bash 中的 __FILE__ 和 __LINE__(Equivalent of __FILE__ and __LINE__ in Bash)

问题 bash 中是否有任何变量包含执行的 .sh 文件的名称? 行号也会很棒。 我想在错误消息中使用它,例如: echo "ERROR: [$FILE:L$LINE] $somefile not found" 回答1 #!/bin/bash echo $LINENO echo `basename $0` $LINENO当前行号$0当前文件。 我使用basename来确保您只获取文件名而不是路径。 更新: #!/bin/bash MY_NAME=`basename $0` function ouch { echo "Fail @ [${MY_NAME}:${1}]" exit 1 } ouch $LINENO 如果您使用函数方法,则必须将该行作为参数传递,否则您将获得函数定义的行。 回答2 我发现“BASH_SOURCE”和“BASH_LINENO”内置数组非常有用: $ cat xx #!/bin/bash _ERR_HDR_FMT="%.23s %s[%s]: " _ERR_MSG_FMT="${_ERR_HDR_FMT}%s\n" error_msg() { printf "$_ERR_MSG_FMT" $(date +%F.%T.%N) ${BASH_SOURCE[1]##*/} ${BASH_LINENO[0]} "${@}" } error_msg "here"

2021-11-29 18:48:46    分类:技术分享    bash   error-handling   environment-variables

通过 exec 在 find 的输出上替换 Bash 变量(Bash variable substitution on find's output through exec)

问题 有没有办法在find的输出上应用bash变量替换? 我知道我已经看到有人在堆栈溢出时这样做了,但我似乎再也找不到那个特定的帖子了。 例如,假设我想将文件*.png重命名为*_copy.png 。 我知道我可以使用rename来做到这一点,但这只是一个思想实验。 现在我希望能够做这样的事情: find . -name "*png" -exec mv "{}" "${{}%.*}_copy.png" \; 这会导致无效替换。 当然,我可以先将输出分配给一个变量,然后在子 shell 中应用替换,但这真的是唯一的方法吗? find . -name "*.png" -exec bash -c 'var="{}"; mv "{}" "${var%.*}_copy.png"' \; 或者有什么方法可以直接从{}实现? 共识 正如Etan Reisner所说,处理 find 输出的更好、更安全的方法是将其作为位置参数传递。 find . -name "*.png" -exec bash -c 'mv "$0" "${0%.*}_copy.png"' "{}" \; 回答1 我花了一段时间才弄明白这个问题。 基本上你在问是否像: echo "${test.png%.png}" 可用于获取单词test 。 答案是不。 以${开头的字符串操作运算符是参数替换运算符的子集。 它们仅适用于变量

2021-11-29 18:41:22    分类:技术分享    bash   find   exec   substitution   built-in

在后台启动一个进程,执行一个任务,然后在后台杀死该进程(Start a process in background, do a task, then kill the process in the background)

问题 我有一个看起来像这样的脚本: pushd . nohup java -jar test/selenium-server.jar > /dev/null 2>&1 & cd web/code/protected/tests/ phpunit functional/ popd selenium 服务器需要运行以进行测试,但是在 phpunit 命令完成后,我想终止正在运行的 selenium 服务器。 我怎样才能做到这一点? 回答1 你大概可以将进程的PID保存在一个变量中,然后使用kill命令将其杀死。 pushd . nohup java -jar test/selenium-server.jar > /dev/null 2>&1 & serverPID=$! cd web/code/protected/tests/ phpunit functional/ kill $serverPID popd 我自己还没有测试过,我想把它写在评论上,但声誉还不够:) 回答2 当脚本被执行时,会创建一个新的 shell 实例。 这意味着新脚本中的jobs不会列出在父 shell 中运行的任何作业。 由于selenium-server服务器是在新脚本中创建的唯一后台进程,因此可以使用 #The first job kill %1 或者 #The last job Same as the

2021-11-29 18:10:09    分类:技术分享    bash   command-line-interface

如何在 BASH 的列中输出数组的内容(How to output an array's content in columns in BASH)

问题 我想显示一个数组中的一长串字符串。 现在,我的脚本通过 for 循环将每个值回显到标准输出: for value in ${values[@]} do echo $value done 是的,太丑了! 一栏列表也很长...... 我想知道是否可以找到一个命令或内置命令来帮助我在列中显示所有这些值,就像ls命令在列出目录 ( ls -C ) 时默认情况下所做的那样。 [更新] 由于column未显示格式正确的column而失去理智,这里有更多信息: 价值: $ values=( 01----7 02----7 03-----8 04----7 05-----8 06-----8 07-----8 08-----8 09---6 10----7 11----7 12----7 13----7 14-----8 15-----8 16----7 17----7 18---6 19-----8 20-----8 21-----8) 请注意前两位数字作为索引,最后一位数字表示可读性的字符串长度。 命令: echo " ${values[@]/%/$'\n'}" | column echo " ${values[@]/%/$'\n'}" | column 结果:坏列 http://tychostudios.ch/multipurpose/bad_columns.png 出事了

2021-11-29 18:07:51    分类:技术分享    arrays   bash   list

监视文件夹内文件更改的 linux 脚本(就像 autospec 一样!)(linux script that monitors file changes within folders (like autospec does!))

问题 我想在文件更改时自动启动构建。 我在 Ruby 中使用过 autospec (RSpec) 并且喜欢它。 这如何在 bash 中完成? 回答1 看看 incron 和 inotify-tools。 回答2 关键字是 inotifywait 和 inotifywatch 命令 回答3 在阅读了其他帖子的回复后,我找到了一个帖子(现在不见了),我创建了这个脚本:- #!/bin/bash sha=0 previous_sha=0 update_sha() { sha=`ls -lR . | sha1sum` } build () { ## Build/make commands here echo echo "--> Monitor: Monitoring filesystem... (Press enter to force a build/update)" } changed () { echo "--> Monitor: Files changed, Building..." build previous_sha=$sha } compare () { update_sha if [[ $sha != $previous_sha ]] ; then changed; fi } run () { while true; do compare read -s -t 1 && (

2021-11-29 17:25:21    分类:技术分享    linux   bash   build   automation   rspec

从 csv 文件中删除 ^M(removing ^M from a csv file)

问题 当我尝试从 csv 中删除 ^M 时遇到问题 当我输入 vim 或 vi file.csv 时,我得到 A, TK,2015-04-06,14.4^M,14.7,10.0,0.0,54.0^M,13.3^M,135.0^M,33.8 B, NV,2015-04-06,14.4^M,14.7,5.4,0.0,47.0^M,14.8^M,97.0^M,31.3 我试过 tr -d '^M' < file.csv > file2.csv 但它并没有删除,也没有删除。 回答1 您可以使用提供的dos2unix命令来执行此操作。 使用 GNU/sed 只是为了好玩: sed -i -e "s/\r//g" file 使用tr : tr -d '\r' <file1 >file2 回答2 你可以试试: perl -pE 's/(\^M|\r)//g' < file >file2 应该删除 文字^M - 两个字符^和M序列和^M作为\r字符。 回答3 你从哪里得到那个文件? 它看起来像来自 Mac 的旧 System X 文件。 旧的 OSX 之前的操作系统使用<CR>作为行尾。 Unix 使用<LF> ,Windows/DOS 使用<CRLF> 。 你有dos2unix。 该程序可以将 Unix/Linux、DOS/Windows 或 System X Mac

2021-11-29 04:45:52    分类:技术分享    bash

如何解析多行记录(使用 awk?)(How to parse multi line records (with awk?))

问题 我试图弄清楚如何从由\n\n分隔的多行记录中提取特定字段。 在这种情况下,它恰好是从类似于 DEBIAN 控制文件的 apt-cache 输出。 查看apt-cache show "$package" Package: caffeine Priority: optional Section: misc Installed-Size: 641 Maintainer: Reuben Thomas <rrt@sc3d.org> Architecture: all Version: 2.8.3 Depends: python3:any (>= 3.3.2-2~), python3, gir1.2-gtk-3.0, gir1.2-appindicator3-0.1, python3-xlib, python3-pkg-resources, libnet-dbus-perl Filename: pool/main/c/caffeine/caffeine_2.8.3_all.deb Size: 58774 MD5sum: 4438db3f6d1cf43a4f4b49cc7f24cda0 SHA1: e748370ac5ccd7de6fc9466ce0451d2e90d179d4 SHA256

2021-11-29 04:35:19    分类:技术分享    regex   linux   bash   awk   sed

使用 ~ 的 Bash 路径变量导致“没有这样的文件或目录”(Bash path variable using ~ resulting in 'No such file or directory')

问题 如果我这样做: ls ~/Dev/Project/Assets/_Core/ 我得到了一个超级骗子目录清单! 好极了! 但如果我这样做: assetsPath=$(head -n 1 .config | perl -ne 'print if s/^assets=(.*)/\1/g') echo $assetsPath ls $assetsPath 我得到: ~/Dev/Project/Assets/_Core/ # this was the variable value from the echo ls: ~/Dev/Project/Assets/_Core/: No such file or directory 我什至尝试使用${assetsPath}但这也不起作用? 回答1 作为部分解决方案: assetsPath=${assetsPath//'~'/$HOME} 这没有解决的是~username扩展; 如果您的assetsPath使用它,那么您需要更多的逻辑(我想我已经在单独的 StackOverflow 答案中添加了它;寻找问题)。 它也没有将~放在不应该扩展的非领先位置。 为了处理这两种极端情况,我将自我剽窃一下: expandPath() { local path local -a pathElements resultPathElements IFS=':'

2021-11-29 04:30:34    分类:技术分享    bash

如何使用xmlstarlet更新xml文件(how to update the xml file using xmlstarlet)

问题 我正在使用 xmlstarlet 的 windows 版本通过 windows 批处理文件更新 xml 文件。 xml edit --update "/xml/table/rec[@id=3]/@id" --value 10 %xmlfile% 我希望这会将 rec 节点的 id 属性更新为 10。当我运行它时,我在命令行中看到更新的 xml,但该文件从未更新。 我该怎么做,我想避免重写整个文件,因为文件可能很大。 更新前: <?xml version="1.0"?> <xml> <table> <rec id="1" /> <rec id="2" /> <rec id="3" /> </table> </xml> 更新后: <?xml version="1.0"?> <xml> <table> <rec id="1" /> <rec id="2" /> <rec id="10" /> </table> </xml> 回答1 您没有显示您的输入文档,但我认为它是以下内容,取自 xmlstarlet 文档: <xml> <table> <rec id="1"> <numField>123</numField> <stringField>String Value</stringField> </rec> <rec id="2"> <numField>346</numField>

2021-11-29 04:27:02    分类:技术分享    xml   bash   xmlstarlet