协助使用bash代码逐行提取数据

时间:2015-05-14 18:55:11

标签: bash loops

我一直在努力使用我正在尝试编写的新bash脚本。

我有一个包含以下内容的文本文件:

/home/user1/public_html/pathtofile1
/home/user2/public_html/pathtofile2
/home/user3/public_html/packtofile3

我需要代码逐行读取文本文件,提取用户名以便我可以暂停它并将完整路径(/ home / user1 / public_html / pathtofile1)作为其被暂停的原因。

我需要它自动执行的示例:

/scripts/suspendacct user1 '/home/user1/public_html/pathtofile1' 1
/scripts/suspendacct user2 '/home/user1/public_html/pathtofile2' 1
/scripts/suspendacct user3 '/home/user1/public_html/pathtofile3' 1

我尝试了“for loop”和“while read line”,但我没有运气。

此外,它还需要排除重复的用户名。

任何输入都将不胜感激。提前谢谢。

3 个答案:

答案 0 :(得分:1)

您可以在bash中使用此while循环:

# already processed users
declare -A seen

while read -r line; do
   IFS=/ read -ra arr <<< "$line"
   u="${arr[2]}"
   [[ ! "${seen[$u]}" ]] && seen["$u"]=1 && /scripts/suspendacct "${arr[2]}" "$line"
done < file

答案 1 :(得分:1)

你的while循环方法很好,你可能在解析line时遇到了麻烦。您可以使用参数扩展/子字符串提取子字符串替换来解析该行所需的信息。以下是参数扩展/子字符串提取的示例:

#!/bin/bash

while read -r line; do
    usr="${line#/*/}"
    usr="${usr%%/*}"
    # /scripts/suspendacct $usr "'$line'"                   # uncomment for use
    printf "/scripts/suspendacct %s '%s'\n" $usr "$line"    # delete for use
done

exit 0

临时输出

$ bash suspendusr.sh <dat/usrpathtofile.txt
/scripts/suspendacct user1 '/home/user1/public_html/pathtofile1'
/scripts/suspendacct user2 '/home/user2/public_html/pathtofile2'
/scripts/suspendacct user3 '/home/user3/public_html/packtofile3'

注意:我只需要打印每个用户/scripts/suspendacct来电的内容。您必须调整脚本并取消注释实际调用。

正如您所知,可能有六种方法可以做到这一点。一切都很好。选择您感觉舒适的方法。

跳过重复

declare -a uarray
declare -i found=0

while read -r line; do
    usr="${line#/*/}"
    usr="${usr%%/*}"
    found=0
    for i in "${uarray[@]}"; do
        [ "$usr" = "$i" ] && found=1;
    done
    [ $found -eq 1 ] && continue
    uarray+=( $usr )
    # /scripts/suspendacct $usr "'$line'"                 # uncomment for use
    printf "/scripts/suspendacct %s '%s'\n" $usr "$line"  # delete for use
done

对每个用户使用单独检查可能比将名称用作正则表达式更好。这将防止任何较少包含的匹配。 (例如user11user111

答案 2 :(得分:0)

尝试以下命令,该命令使用单一管道完全避免在shell中循环

sort -t/ -k3,3 -u file | 
  awk -F/ '{ print $3 "\t" $0 }' | 
    xargs -n 2 -J {} echo /scripts/suspendacct {} 1

删除上面的echo以实际运行suspendacct

  • sort -t/ -k3,3 -u file按用户名排序输入文件(第3个字段(-k3,3),基于分隔符/-t/))并删除重复的用户名({{1} })。
  • -u将用户名添加到每个输入行:
    • awk -F/ '{ print $3 "\t" $0 }'是第3个字段,基于分隔符$3/)。
    • -F/是整个输入行。
  • $0 为输入中以空格分隔的标记的每个xargs -n 2 -J {} /scripts/suspendacct {} 1)调用/scripts/suspendacct,即为每个用户名 - 路径对调用-n 2
    • 请注意,假设用户名和路径都没有嵌入的空格(用户名的安全假设) - 如果他们这样做了,那么也可以解决;为简洁起见,此处并未涉及。
    • -J {}只是为参数的位置定义占位符{}