AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / user-245871

annahri's questions

Martin Hope
annahri
Asked: 2023-09-01 11:37:30 +0800 CST

Bash mapfile 数组计数不同

  • 5

我做了以下事情:

mapfile -t array < <(commands)

其中commands将产生换行符分隔的输出。

然后根据结果,如果数组中没有任何内容,则退出,否则继续:

[[ "${#array[@]}" -eq 0 ]] && exit

...

问题是这个条件永远不会被满足。因为当 saidcommands不返回任何内容时,${#array[@]}返回 1 而不是 0。

但如果我按如下方式分配数组,则计数正确:

array=($(commands))

我的测试:

$ declare -a array
$ array=($(echo))
$ echo ${#array[@]}
0
$ unset array
$ mapfile -t array < <(echo)
$ echo ${#array[@]}
1

为什么?


最初我使用了该array=($(commands))格式,但shellcheck建议我改为使用mapfile。

GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)
bash
  • 1 个回答
  • 37 Views
Martin Hope
annahri
Asked: 2022-10-09 18:39:26 +0800 CST

在 BEGIN 块中设置 RS 时跳过 AWK 中的第一行

  • -1

我有以下输入文件:

-Queue ID-  --Size-- ----Arrival Time---- -Sender/Recipient-------
0F2F77F472  4343854 Fri Oct  7 10:13:41  [email protected]
(host redacted.host.com[x.x.x.x] said: 452 4.2.2 Over quota (in reply to end of DATA command))
                                         [email protected]

03A017F486   992790 Fri Oct  7 13:09:44  [email protected]
(host host.redacted.net[y.y.y.y] said: 452-4.2.2 The email account that you tried to reach is over quota. Please direct 452-4.2.2 the recipient to 452 4.2.2  redacted (in reply to RCPT TO command))
                                         [email protected]

在我的 AWK 脚本中,我写了如下内容:

BEGIN {
  RS = "\n\n"
}

{
  ... do something ...
}

标头也会得到处理,因此在我的管道中,在传递给 AWK 之前,我会:

... | tail +2 | awk -f script

我承认要跳过 AWK 中的第一行,主要是通过这个简单的技巧:

{
  if (NR > 1) {
    ...
  }
}

它应该可以工作,但是RS = "\n\n"我在BEGIN块中设置的会忽略第一条记录(AWK 将标头解释为第一条记录的一部分)。

测试:

$ awk 'BEGIN { RS = "\n\n" } { print NF }' sample
28
41

$ awk 'BEGIN { RS = "\n\n" } NR > 1 { print NF }' sample
41

有什么方法可以在不依赖任何外部工具的情况下实现目标?


GNU Awk 5.0.1, API: 2.0 (GNU MPFR 4.0.2, GNU MP 6.2.0)
awk
  • 1 个回答
  • 32 Views
Martin Hope
annahri
Asked: 2022-02-13 04:01:01 +0800 CST

此 sed 语法不会删除空行

  • 0

我有这个输入文件:

...
https://long-url/something?value1=999&something=xyz?value2=555
https://long-url/something?value1=534&something=xyz?value2=2312


https://long-url/something?value1=534&something=xyz?value2=233
https://long-url/something?value1=534
...

我想捕获 value1 和 value2 并将它们输出为 csv,并删除任何不匹配的行:

...
999,555
534,2312
534,233
...

我在捕获值方面没有问题,但我在删除任何不需要的行时遇到了问题:

sed 's/.*categoryid=\([0-9]*\).*courseid=\([0-9]*\).*/\1,\2/g;/^[^0-9]\+/d' input-file

基本上,/^[^0-9]\+/d它没有按预期工作。我在想它会删除任何不以任何数字开头的行,但相反,它给了我:

999,555
534,2312


534,233

我的 sed 版本:sed (GNU sed) 4.7

sed
  • 3 个回答
  • 44 Views
Martin Hope
annahri
Asked: 2020-03-07 17:30:27 +0800 CST

logrotate 执行的脚本与手动执行的结果不同

  • 1

我想使用logrotate. 每次轮换后,它都会执行一个脚本,将所有轮换的日志移动到另一个目录。例如/home/dev/logs/frontend,我有这些日志文件:

webapp1-access.log
webapp2-access.log
anotherapp3-access.log
codename-access.log
...

还有我的 logrotate 配置文件:

$ cat app.daily
/home/dev/logs/frontend/*access.log {
   rotate 1
   daily
   copytruncate
   compress
   notifempty
   missingok
   lastaction
      bash /path/to/script.sh
   endscript
}

script.sh 所做的是根据日志文件名创建一个目录,然后将旋转的日志文件移动到那里。将webapp1-access.log被旋转到,webapp1-access.log.1.gz然后脚本会将其移动到/x/y/webbapp1/renamed.log.gz。对于其他轮换日志,依此类推。

当我使用 测试 logrotatelogrotate -fv /path/to/config时,它​​按我的预期完美运行。然后我将 logrotate 配置文件放入/etc/logrotate.d(作为符号链接)。

第二天我检查了/x/y目录,我得到了:

webbapp1/                       <---- created from initial logrotate -fv
webbapp1-access.log/            <---- Unexpected
anotherapp3/                    <---- created from initial logrotate -fv
anotherapp3-access.log/         <---- Unexpected
codename/                       <---- created from initial logrotate -fv
codename-access.log/            <---- Unexpected

目录由*-access.log/logrotate 创建。但是logrotate -vf config多次运行不会产生意想不到的结果。当我离开 logrotate 进行每日轮换时,就会发生这种情况。

为什么会这样?我怎样才能解决这个问题?


script.sh

#! /usr/bin/bash

exec 3>> /var/log/archived-log.log
[ "${1:-}" = "-d" ] && debug=1

environment="frontend"

rotateddir="/home/dev/logs/$environment"
destdir="/x/y"
[ "${debug:-}" ] && echo "DEST DIR: $destdir"

log() {
    timestamp=$(date +"%Y-%m-%d %H:%M:%S")
    echo "$timestamp: $1" >&3
}

for archive in $rotateddir/*.gz; do
    [ "${debug:-}" ] && echo "ARCHIVE: $archive"
    [ "${archive##*/}" = "*.gz"  ] && continue
    base_name=$(basename "$archive")
    [ "${debug:-}" ] && echo "BASENAME: $base_name"
    extension="${base_name##*.}"
    [ "${debug:-}" ] && echo "EXT: $extension"
    newdir_name="${base_name%-*}"
    [ "${debug:-}" ] && echo "NEWDIR_NAME: $newdir_name"
    tanggal=$(stat -c %y "$archive" | cut -d" " -f1 | { read dat; date -d $dat +%Y%m%d; })
    #jam=$(stat -c %y "$archive" | cut -d" " -f2 | { read dat; date -d $dat +%H%M; })
    newdir_path="$destdir/$newdir_name"
    [ "${debug:-}" ] && echo "NEWDIR_PATH: $newdir_path"
    #dest_archive="$newdir_path/$tanggal-$jam.log.$extension"
    dest_archive="$newdir_path/$tanggal.log.$extension"
    [ "${debug:-}" ] && echo "DEST_ARCHIVE: $dest_archive"

    [ ! -d "$newdir_path" ] && {
        if [ "${debug:-}" ]; then
            echo "Would create $newdir_path"
        else
            mkdir -p "$newdir_path"
            log "Created directory: $newdir_path"
        fi
    }

    [ ! -f "$dest_archive" ] && {
        if [ "${debug:-}" ]; then
            echo "Would move $archive to $dest_archive"
        else
            rsync -a --no-owner --no-group --remove-source-files "$archive" "$dest_archive"
            #cp -u --no-preserve=mode,ownership "$archive" "$dest_archive" && rm -f "$archive"
            log "Relocated $archive to $dest_archive"
        fi
    }

    rotates=$(ls -1 "$newdir_path" | wc -l )
    [ "$rotates" -ge 7 ] && {
        oldest=$(ls -t "$newdir_path" | tail -1)
        if [ "${debug:-}" ]; then
            echo "Would delete the oldest archive: $oldest"
        else
            rm -f "$newdir_path/$oldest"
            log "Deleted oldest archive of $base_name : $oldest"
        fi
    }   
done

exit 0



更新

我仍然不知道为什么会发生这种情况,但最后我决定在轮换几分钟后通过 cron 运行脚本。

我怀疑我的“script.sh”newdir_name="${base_name%-*}"的这一部分没有被logrotate. 但是同样,如果我使用强制运行它,它会按预期工作logrotate -fv config

bash shell-script
  • 1 个回答
  • 171 Views
Martin Hope
annahri
Asked: 2020-02-21 02:08:01 +0800 CST

` ... | awk '$1=$1'` 删除多余的空格?

  • 20

据我了解,$1是第一个领域。但奇怪的是,awk '$1=$1'省略了额外的空格。

$ echo "$string"
foo    foo bar               bar

$ echo "$string" | awk '$1=$1'
foo foo bar bar

为什么会这样?

awk
  • 2 个回答
  • 6532 Views
Martin Hope
annahri
Asked: 2020-02-10 23:08:51 +0800 CST

GNU coreutils `sort` 的行为不同

  • 0

我想对数据列表进行排序,并打算根据其第一列(即 IP 地址)对其进行排序。

192.168.1.100
192.168.1.101
192.168.1.110
192.168.1.119
192.168.1.20
192.168.1.30
192.168.1.33
192.168.1.54
192.168.1.64
192.168.1.6
192.168.1.91

在我的第一台机器上,我进行了测试sort -n,它按预期工作

# coreutils, version: 8.31, release: 23

192.168.1.6
192.168.1.20
192.168.1.30
192.168.1.33
192.168.1.54
192.168.1.64
192.168.1.91
192.168.1.100
192.168.1.101
192.168.1.110
192.168.1.119

但是在我的第二台机器上,它不能正确排序

# coreutils, version:8.4

192.168.1.100
192.168.1.101
192.168.1.110
192.168.1.119
192.168.1.20
192.168.1.30
192.168.1.33
192.168.1.54
192.168.1.6
192.168.1.64
192.168.1.91

两台机器具有相同的语言环境en_US.UTF-8


为什么会这样?我该如何解决?

linux shell
  • 1 个回答
  • 234 Views
Martin Hope
annahri
Asked: 2020-02-04 21:59:36 +0800 CST

为什么这个积极的前瞻正则表达式 'string.*?(?= )' 在 sed 中不起作用?[复制]

  • 5
这个问题在这里已经有了答案:
sed 中是否有零宽度断言? (1 个回答)
为什么我的正则表达式在 X 中有效,但在 Y 中无效? (1 个回答)
2年前关闭。

我有一长串类似的东西:

AllowedUsers [email protected] [email protected] [email protected] [email protected] .....

全部在单行中。基本上是一堆用户名@ip

我想通过使用它的用户名(例如aaa)来进行查找和替换,然后什么都不替换。

我测试了我的正则表达式(RegExr),它按我的预期工作。但是,当我尝试在 上进行操作时sed,它没有用。

$ sed 's/bbbb11.*?(?= )//' test
AllowedUsers [email protected] [email protected] [email protected] [email protected] .....

我也试过用bbbb11.*?(?=[[:space:]]),也没用。

我错过了什么?

text-processing sed
  • 1 个回答
  • 4485 Views
Martin Hope
annahri
Asked: 2020-01-25 16:50:17 +0800 CST

如何 ssh 并运行包含在 if else 中的多个命令?

  • 2

我想使用 ssh 从各种服务器捕获一些数据并在某些条件下运行一些命令。

我不想这样做:

if ssh $host test -f /file; then
  # If file exists
  var=$(ssh $host long pipeline)
else
  # if it doesn't
  var=$(ssh $host another long pipeline)
fi

因为它会使过程更长。我想在远程机器上执行 if else 。


我尝试了几种方法,但我没有运气。

var=$(ssh $host if [ -f /file ]\; then long pipeline1 \; else long pipeline2 \; fi)

基于这个答案,它可以工作,但 pipeline1 的最后一个命令假定它else和 pipeline2 的其余部分作为它的参数。

command: can't read else: No such file or directory
...
command: can't read fi: No such file or directory

然后我尝试了这个

var=$(ssh $host test -f /file \&\& pipeline1 \|\| pipeline2)

同样, pipeline1 的最后一个命令被||视为其参数。


我也在下面尝试过(基于this),它正在工作:

do_this () {
  if [ -f /file ]; then
    pipeline1
  else
    pipeline2
  fi
}
var=$(ssh $host "$(set); do_this")

然而,它会打印不影响我的变量的不需要的错误消息,但它对我的脚本来说很难看。

bash: line 1: BASHOPTS: readonly variable
bash: line 8: BASH_VERSINFO: readonly variable
bash: line 24: EUID: readonly variable
bash: line 71: PPID: readonly variable
bash: line 82: SHELLOPTS: readonly variable
bash: line 92: UID: readonly variable

有什么建议么?


更新

我想我必须包括我的管道是什么,基本上它只是一堆文本处理:

cat file | grep "something" | sed 's/.*="\(.*\)"/\1/' | tr ' ' '-'

根据Jetchisel的回答,简而言之,我必须用单引号括起我的命令。

var=$(ssh $host 'if [ -f /file ]; then cat file | grep "something" | sed 's/.*="\(.*\)"/\1/' | tr ' ' '-' ; else cat otherfile | ... ; fi'

我得到了tr: invalid option -- ';'。tr当作;它的论据。


它使用heredoc:

var=$(ssh $host <<-EOF
  if [ -f file ]; then
    pipeline1
  else
    pipeline2
  fi
EOF
)

然而,由于我在 sed 中使用的正则表达式,它破坏了 vim 的着色。我现在会接受heredoc作为答案。


更新 2:我相信我的问题不是sshpass 中的多个命令的重复,我的情况更具体,而另一个线程一般会问它。

bash shell-script
  • 2 个回答
  • 1395 Views
Martin Hope
annahri
Asked: 2019-07-22 14:54:14 +0800 CST

如何附加到每行的末尾?

  • 0

我有这个文件,ipaddresses.txt

152.48.64.13
146.112.164.43
236.157.219.229
188.201.225.93
193.140.79.73
...

而这个文件,cidr.txt

20
21
8
20
21
...

我希望输出文件是这样的:

152.48.64.13/20
146.112.164.43/21
236.157.219.229/8
188.201.225.93/20
193.140.79.73/21
...

如何做到这一点?

text-processing
  • 1 个回答
  • 337 Views

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve