如标题 - 我想将输入文件/stdin 中的制表符转换为 stdout/重定向文件上的 asciii 单位分隔符。
以下均无效
tr 0x09 0x1f
tr '0x09' '0x1f'
sed 's#0x09#0x1f#g'
sed s#0x09#0x1f#g
没有效果
如标题 - 我想将输入文件/stdin 中的制表符转换为 stdout/重定向文件上的 asciii 单位分隔符。
以下均无效
tr 0x09 0x1f
tr '0x09' '0x1f'
sed 's#0x09#0x1f#g'
sed s#0x09#0x1f#g
没有效果
我需要根据以下情况删除 JPG 和 jpg 文件
文件夹有多个 JPG 和 jpg 文件。每个文件的名称例如:172.30.165.212_20241231_132125.JPG
。其中172.30.165.212
是 IP 地址,20241231
是 YYYYMMDD 格式的日期,132125
是 HHMMSS 格式的时间。
删除条件如下:
1- 脚本应始终根据文件名的日期/时间保留每个 IP 地址的最新文件。无论日期/时间有多旧。2-
但是,由于每个 IP 地址可以有多个文件,因此脚本应删除文件名中的日期/时间比当前时间早 2 小时以上的所有文件。3-
永远不要查看文件的修改日期/时间,只查看名称中的修改日期/时间。
我尝试过这个,但没有成功,因为文件没有被删除。
#!/bin/bash
# Define target directory
TARGET_DIR="/mnt/moe/results"
# Log start time
echo "[$(date)] Starting cleanup process in $TARGET_DIR"
# Function to process files for a single IP
process_ip_files() {
local ip_prefix=$1
local ip_files
# Find files matching the IP
ip_files=$(find "$TARGET_DIR" -type f -iname "${ip_prefix}_*" | sort)
# Skip if no files
if [[ -z "$ip_files" ]]; then
echo "No files found for IP: $ip_prefix"
return
fi
echo "Processing IP: $ip_prefix"
# Variables to track files and the most recent file
local most_recent_file=""
local most_recent_time=0
local files_to_delete=()
# Get current time in seconds since epoch
current_time=$(date +%s)
# Iterate over files to determine the most recent and deletion criteria
while IFS= read -r file; do
echo "Processing file: $file"
# Remove the path and get just the file name
base_file=$(basename "$file")
echo "Base file name: $base_file"
# Split file name into components
IFS='_' read -r ip date time ext <<< "$base_file"
# Validate the expected number of fields and format
if [[ -z "$ip" || -z "$date" || -z "$time" || "$ext" != "JPG" && "$ext" != "jpg" ]]; then
echo " Skipping file (does not match expected format): $file"
continue
fi
# Check the timestamp format (YYYYMMDD HHMMSS)
if ! [[ "$date" =~ ^[0-9]{8}$ ]] || ! [[ "$time" =~ ^[0-9]{6}$ ]]; then
echo " Skipping file (invalid timestamp format): $file"
continue
fi
# Convert to seconds since epoch
timestamp="$date $time"
file_time=$(date -d "$timestamp" +%s)
echo " File: $file"
echo " Timestamp: $timestamp"
echo " File time (epoch): $file_time"
echo " Current time (epoch): $current_time"
# Check if this file is the most recent one for the IP
if (( file_time > most_recent_time )); then
# If we already have a most recent file, we add it to the delete list
if [[ -n "$most_recent_file" ]]; then
files_to_delete+=("$most_recent_file")
fi
most_recent_file="$file"
most_recent_time="$file_time"
else
# Check if the file is older than 2 hours (7200 seconds)
if (( current_time - file_time > 7200 )); then
echo " Marking for deletion: $file"
files_to_delete+=("$file")
fi
fi
done <<< "$ip_files"
# Display the most recent file for this IP
echo "Most recent file for IP $ip_prefix: $most_recent_file"
# Deleting files not the most recent one
if [[ ${#files_to_delete[@]} -gt 0 ]]; then
echo "Files marked for deletion for IP $ip_prefix:"
for file in "${files_to_delete[@]}"; do
echo " - $file"
done
for file in "${files_to_delete[@]}"; do
if [[ "$file" != "$most_recent_file" ]]; then
echo "Deleting file: $file"
rm -v "$file"
fi
done
else
echo "No files to delete for IP $ip_prefix."
fi
}
# Process unique IP addresses
find "$TARGET_DIR" -type f \( -iname "*.jpg" -o -iname "*.JPG" \) -printf "%f\n" | \
awk -F'_' '{print $1}' | sort -u | while read -r ip; do
process_ip_files "$ip"
done
# Log completion
echo "[$(date)] Cleanup process finished."
例如,我有以下文件,当前日期/时间是 20241231 13:30
172.30.165.212_20241231_132125.JPG
172.30.165.212_20241231_122125.JPG
172.30.165.212_20241231_112125.JPG
172.30.165.212_20241231_102125.JPG
172.30.165.212_20241231_092125.JPG
172.30.165.213_20241231_062125.JPG
172.30.165.213_20241231_032125.JPG
172.30.165.213_20241231_012125.JPG
脚本应该删除
172.30.165.212_20241231_112125.JPG (older than 2 hours)
172.30.165.212_20241231_102125.JPG (older than 2 hours)
172.30.165.212_20241231_092125.JPG (older than 2 hours)
172.30.165.213_20241231_032125.JPG (older than 2 hours)
172.30.165.213_20241231_012125.JPG (older than 2 hours)
脚本应该保留
172.30.165.212_20241231_132125.JPG (younger than 2 hours)
172.30.165.212_20241231_122125.JPG (younger than 2 hours)
172.30.165.213_20241231_062125.JPG (older than 2 hours but most recent from this ip address)
我正在尝试获取某些日志的日期,以某种格式进行一些比较,这是我的命令:
fgrep "<expression>" <logFile> | sort | awk -F "[][]" 'messageDate=$(date -d "$2" "+%Y.%j.%H.%M.%S") { print messageDate }'
我打印的是日志文件的完整行。
如果我运行这个:
fgrep "<expression>" <logFiles> | sort | awk -F "[][]" 'messageDate=$(date -d "$2" "+%Y.%j.%H.%M.%S") { print $2 }'
我得到了日期但不是我想要的格式。
2014-09-04T08:22:16Z
2017-10-08T16:05:06Z
2022-11-30T14:50:16Z
日志文件包含如下消息:
[2022-11-30T14:50:16Z] <Info/Warning/Error>: <log message>
有谁明白为什么 awk 可以工作,这意味着它正确地分割文件,但是代码messageDate=$(date -d "$2" "+%Y.%j.%H.%M.%S")
以某种方式再次获取完整的日志消息?
每个文件的第一行包含字段名称。字段名称中可能存在重复。我只想打印唯一的字段名称。以下是我尝试的:
在 Bash 文件 files_and_folders.sh 中,我输入了以下内容:
#!/bin/bash
for file in **/*.TXT ; do
awk 'NR == 1 { for (i=1; i<=NF; i++) if (!seen[$i]) seen[$i] = 1} END { for (idx in seen) printf ("%s\n",idx) }' "${file}"
done
Bash 文件成功运行,但输出包含重复项:
AB_CODE
ACFT_CODE
AC_TYPE
ADD_INFO
AKA
ALT
ALT
ALT
ALT
ALT
ALT
ALT
ALT1_DESC
ALT2_DESC
ALT3_DESC
如何修改 AWK 程序(在 Bash 脚本中)以消除重复?
我想在 bash 下使用 printf 来格式化德语动词,如下所示:
INFINITIV PRATERITUM PERFEKT 3.PERS. SING
heißen hieß hat geheißen er heißt
kaufen kaufte hat gekauft er kauft
我在我的 bash 脚本中使用了一个简单的 printf 命令:
printf "%-15s %-15s %-15s %-15s %-15s\n" "INFINITIV" "PRATERITUM" "PERFEKT" "3.PERS. SING"
printf "%-15s %-15s %-15s %-15s %-15s\n" "heißen" "hieß" "hat geheißen" "er heißt"
printf "%-15s %-15s %-15s %-15s %-15s\n" "kaufen" "kaufte" "hat gekauft" "er kauft"
但似乎 Eszett 被视为两个字符。因此,屏幕上每次出现 ß 后,文本都会向左移动一个位置。输出为:
pwp@linuxcomputers:~/Scripts/Test$ Deutsche-Verben-Scharf-S
INFINITIV PRATERITUM PERFEKT 3.PERS. SING
heißen hieß hat geheißen er heißt
kaufen kaufte hat gekauft er kauft
我怎样才能防止这种转变并使 printf 格式按照预期进行?
看到一些让我怀疑自己理智的事情:
#!/bin/env bash
set -e
for d in '/tmp/somedir/*'; do
for f in "${d}/*pub"; do
echo $f;
done
done
它按预期返回
/tmp/somedir/AAA/fileaa.pub /tmp/somedir/BBB/filebb.pub
但是,如果我改为echo $f
或echo "$f"
我echo "${f}"
得到:
/tmp/somedir/*/*pub
我很难理解为什么。首先,这是一个单独的项目,所以它不只是影响生产echo
线的东西。
使用GNU bash, version 5.2.37(1)-release (x86_64-pc-linux-gnu)
这是该主机上的商店
assoc_expand_once off
cdable_vars off
cdspell off
checkhash off
checkjobs off
checkwinsize on
cmdhist on
compat31 off
compat32 off
compat40 off
compat41 off
compat42 off
compat43 off
compat44 off
complete_fullquote on
direxpand off
dirspell off
dotglob off
execfail off
expand_aliases on
extdebug off
extglob on
extquote on
failglob off
force_fignore on
globasciiranges on
globskipdots on
globstar off
gnu_errfmt off
histappend on
histreedit off
histverify off
hostcomplete off
huponexit off
inherit_errexit off
interactive_comments on
lastpipe off
lithist off
localvar_inherit off
localvar_unset off
login_shell off
mailwarn off
no_empty_cmd_completion off
nocaseglob off
nocasematch off
noexpand_translation off
nullglob off
patsub_replacement on
progcomp on
progcomp_alias off
promptvars on
restricted_shell off
shift_verbose off
sourcepath on
varredir_close off
xpg_echo off
我是 Bash 脚本编程的新手,我正在尝试理解以下代码:
tmp_file=/tmp/tmp_file$$
mkfifo $tmp_file
echo "msg_A" >$tmp_file # blocks, since pipe is unbuffered and no one is reading from it
read msg <$tmp_file
echo $msg
tmp_file=/tmp/tmp_file$$
mkfifo $tmp_file
exec 7<>$tmp_file # add this line
echo "msg_A" >$tmp_file # now, the write operation won't block, why?
read msg <$tmp_file
echo $msg # msg_A is printed
我想知道exec 7<>$tmp_file
上面的代码示例中做了什么,以及为什么添加此行会使写入操作非阻塞?
我有一个使用 yq 读取的文件,并且必须使用 kustomization 模板中的 yaml 格式的配置。因此,我从文件读取配置的方式如下:
istio_ns_scoping_labels=$(yq -r '.cluster.config.istio_ns_scoping_labels' "$config_file" 2>/dev/null)
echo "$istio_ns_scoping_labels"
#istio_ns_scoping_labels
[
{
"istio-discovery": "enabled"
},
{
"kubernetes.io/metadata.name": "keycloak-idc-identity-broker"
},
{
"kubernetes.io/metadata.name": "keycloak-idc-identity-broker-2"
},
{
"kubernetes.io/metadata.name": "keycloak-idc-identity-broke-3"
}
]
现在我想将其格式化为 yaml,以便可以将其替换为 yaml 模板,如下所示
discoverySelectors:
- matchLabels:
istio-discovery: enabled
- matchLabels:
kubernetes.io/metadata.name: keycloak-idc-identity-broker
- matchLabels:
kubernetes.io/metadata.name: keycloak-idc-identity-broker-2
- matchLabels:
kubernetes.io/metadata.name: keycloak-idc-identity-broker-3
我必须确保 $labels 格式正确为 yaml 格式,因为我使用 envsubst 来替换模板内部的块,如下所示
meshConfig:
accessLogFile: /dev/stdout
discoverySelectors:
- matchLabels:
${MATCH_LABELS_BLOCK}
我正在使用 yq 从 config.yml 文件中读取标签配置,如下所示
config_file=cluster.yml
istio_ns_scoping_labels=$(yq -r '.cluster.config.istio_ns_scoping_labels' "$config_file" 2>/dev/null)
#cluster.yml
cluster:
config:
istio_ns_scoping_labels:
istio-discovery: enabled
kubernetes.io/metadata.name: keycloak-idc-identity-broker
这是 awk gsub 的延续,没有替换字段中所有句点实例。
我有一些意见:
$ cat ./ipv4settings.txt
ipv4.gateway: 192.168.2.1
ipv4.routes: --
ipv4.route-metric: -1
ipv4.route-table: 0 (unspec)
我能够生成所需的输出(某种程度上):
$ awk 'BEGIN{FS=":[[:space:]]+";OFS="="}{gsub("[.]|-","_",$1);$1=$1;print $1"="$2 }' ./ipv4settings.txt
ipv4_gateway=192.168.2.1
ipv4_routes=--
ipv4_route_metric=-1
ipv4_route_table=0 (unspec)
接下来我要为每一行输出声明变量。我使用了几种变体declare
:
$awk 'BEGIN{FS=":[[:space:]]+";OFS="="}{gsub("[.]|-","_",$1);$1=$1;print $1"="$2 }' ./ipv4settings.txt
ipv4_gateway=192.168.2.1
ipv4_routes=--
ipv4_route_metric=-1
ipv4_route_table=0 (unspec)
$ declare $( awk 'BEGIN{FS=":[[:space:]]+";OFS="="}{gsub("[.]|-","_",$1);$1=$1;print $1"="$2 }' ./ipv4settings.txt )
-bash: declare: `(unspec)': not a valid identifier
awk
我尝试引用(declare not a valid identifier bash )的整行输出(https://www.baeldung.com/linux/awk-print-quote-characters):
$ awk 'BEGIN{FS=":[[:space:]]+";OFS="="}{gsub("[.]|-","_",$1);$1=$1;print "\042"$1"="$2"\042" }' ./ipv4settings.txt
"ipv4_gateway=192.168.2.1"
"ipv4_routes=--"
"ipv4_route_metric=-1"
"ipv4_route_table=0 (unspec)"
$ declare $( awk 'BEGIN{FS=":[[:space:]]+";OFS="="}{gsub("[.]|-","_",$1);$1=$1;print "\042"$1"="$2"\042" }' ./ipv4settings.txt )
-bash: declare: `"ipv4_gateway=192.168.2.1"': not a valid identifier
-bash: declare: `"ipv4_routes=--"': not a valid identifier
-bash: declare: `"ipv4_route_metric=-1"': not a valid identifier
-bash: declare: `"ipv4_route_table=0': not a valid identifier
-bash: declare: `(unspec)"': not a valid identifier
...或者仅仅是价值部分:
$ awk 'BEGIN{FS=":[[:space:]]+";OFS="="}{gsub("[.]|-","_",$1);$1=$1;print $1"=\042"$2"\042" }' ./ipv4settings.txt
ipv4_gateway="192.168.2.1"
ipv4_routes="--"
ipv4_route_metric="-1"
ipv4_route_table="0 (unspec)"
$ declare $( awk 'BEGIN{FS=":[[:space:]]+";OFS="="}{gsub("[.]|-","_",$1);$1=$1;print $1"=\042"$2"\042" }' ./ipv4settings.txt )
-bash: declare: `(unspec)"': not a valid identifier
如何处理declare
带有空格的变量值?
我有一些 spring boot 微服务。我想使用 docker compose 运行它们。为了确保服务按顺序运行,我使用 .sh 文件在其他服务之前运行其中一个,因为其他微服务依赖于它。bash 脚本文件运行良好,但它会停止调用者容器。我在互联网上搜索并意识到必须在 bash 脚本文件末尾添加一些命令:/cnb/process/web
或./cnb/lifecycle/launcher
才能继续该过程。但显示此消息: /cnb/process/web: No such file or directory
。
Spring Boot 版本:3.2.2
Docker 撰写:3.8
.sh 文件:
#!/bin/bash
# check-config-server-started.sh
apt-get update -y
yes | apt-get install curl
curlResult=$(curl -s -o -I -w "%{http_code}" http://cloud-config-server:8888/actuator/health)
echo "result status code:" "$curlResult"
while [[ ! $curlResult == "200" ]]; do
>&2 echo "Config server is not up yet!"
sleep 2
curlResult=$(curl -s -o -I -w "%{http_code}" http://cloud-config-server:8888/actuator/health)
done
/cnb/process/web
#./cnb/lifecycle/launcher
Docker 撰写文件:
version: "3.8"
services:
cloud-config-server:
container_name: cloud-config-server-container
build:
dockerfile: ./cloud-config-server/Dockerfile
ports:
- "8888:8888"
environment:
- "SERVER_PORT=8888"
networks:
my-compose-net:
restart: on-failure
webapp:
container_name: webapp-container
build:
dockerfile: ./webapp/Dockerfile
ports:
- "8081:8081"
volumes:
- "./check-config-server-started.sh:/usr/local/bin/check-config-server-started.sh"
user: root
entrypoint: [ "check-config-server-started.sh" ]
environment:
- "SPRING_CLOUD_CONFIG_URI=http://cloud-config-server:8888"
depends_on:
- cloud-config-server
networks:
my-compose-net:
restart: on-failure
networks:
my-compose-net: