BASHプログラミング
 Computer >> コンピューター >  >> プログラミング >> BASHプログラミング

大規模なファイルシステムでこのBashスクリプトを試してください

ディレクトリ内のすべてのファイルを一覧表示したいが、ファイルだけを一覧表示したいと思ったことはありませんか?ディレクトリだけはどうですか?持っている場合は、GPLv3の下でオープンソースである次のスクリプトがあなたが探していたものである可能性があります。

もちろん、検索を使用することもできます コマンド:

find . -maxdepth 1 -type f -print

しかし、これは入力が面倒で、不親切な出力を生成し、 lsの洗練された部分が欠けています。 指図。 lsを組み合わせることもできます およびgrep 同じ結果を達成するには:

ls -F . | grep -v /

しかし、繰り返しますが、これは不格好です。このスクリプトは簡単な代替手段を提供します。

使用法

スクリプトは、呼び出す名前に応じて4つの主要な関数を提供します。 lsf ファイルを一覧表示します、 lsd ディレクトリを一覧表示します、 lsx 実行可能ファイルを一覧表示し、 lsl リンクを一覧表示します。

シンボリックリンクが機能するため、スクリプトの複数のコピーをインストールする必要はありません。これにより、スペースが節約され、スクリプトの更新が容易になります。

スクリプトは、検索を使用して機能します 検索を実行するコマンドを実行すると、 lsが実行されます それが見つける各アイテムに。これの良いところは、スクリプトに与えられた引数がすべて lsに渡されることです。 指図。したがって、たとえば、ドットで始まるファイルも含めて、すべてのファイルが一覧表示されます。

lsf -a

ディレクトリを長い形式で一覧表示するには、 lsdを使用します コマンド:

lsd -l

複数の引数を指定でき、ファイルとディレクトリのパスも指定できます。

これにより、現在のディレクトリの親ディレクトリと / usr / binにあるすべてのファイルの長い分類リストが提供されます。 ディレクトリ:

lsf -F -l .. /usr/bin

ただし、スクリプトが現在処理していないことの1つは、再帰です。このコマンドは、現在のディレクトリ内のファイルのみを一覧表示します。

lsf -R

スクリプトはサブディレクトリに分類されません。これはいつか修正される可能性があります。

内部

スクリプトはトップダウン方式で記述されており、スクリプトの最初に初期機能があり、最後に作業の本体が実行されます。スクリプトで本当に重要な関数は2つだけです。 parse_args() functionはコマンドラインを熟読し、オプションをパス名から分離し、特定のオプションを lsからスクリプト化します。 コマンドラインオプション。

list_things_in_dir() 関数は、引数としてディレクトリ名を取り、検索を実行します その上でコマンド。見つかった各アイテムはlsに渡されます 表示用のコマンド。

結論

これは、単純な機能を実行するための単純なスクリプトです。これは時間の節約になり、大規模なファイルシステムで作業するときに驚くほど便利です。

スクリプト
#!/bin/bash

# Script to list:
#      directories (if called "lsd")
#      files       (if called "lsf")
#      links       (if called "lsl")
#  or  executables (if called "lsx")
# but not any other type of filesystem object.
# FIXME: add lsp   (list pipes)
#
# Usage:
#   <command_name> [switches valid for ls command] [dirname...]
#
# Works with names that includes spaces and that start with a hyphen.
#
# Created by Nick Clifton.
# Version 1.4
# Copyright (c) 2006, 2007 Red Hat.
#
# This is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published
# by the Free Software Foundation; either version 3, or (at your
# option) any later version.

# It is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# ToDo:
#  Handle recursion, eg:  lsl -R
#  Handle switches that take arguments, eg --block-size
#  Handle --almost-all, --ignore-backups, --format and --ignore

main ()
{
  init
 
  parse_args ${1+"$@"}

  list_objects

  exit 0
}

report ()
{
  echo $prog": " ${1+"$@"}
}

fail ()
{
  report " Internal error: " ${1+"$@"}
  exit 1
}

# Initialise global variables.
init ()
{
  # Default to listing things in the current directory.
  dirs[0]=".";
 
  # num_dirs is the number of directories to be listed minus one.
  # This is because we are indexing the dirs[] array from zero.
  num_dirs=0;
 
  # Default to ignoring things that start with a period.
  no_dots=1
 
  # Note - the global variables 'type' and 'opts' are initialised in
  # parse_args function.
}

# Parse our command line
parse_args ()
{
  local no_more_args

  no_more_args=0 ;

  prog=`basename $0` ;

  # Decide if we are listing files or directories.
  case $prog in
    lsf | lsf.sh)
      type=f
      opts="";
      ;;
    lsd | lsd.sh)
      type=d
      # The -d switch to "ls" is presumed when listing directories.
      opts="-d";
      ;;
    lsl | lsl.sh)
      type=l
      # Use -d to prevent the listed links from being followed.
      opts="-d";
      ;;
    lsx | lsx.sh)
      type=f
      find_extras="-perm /111"
      ;;    
    *)
      fail "Unrecognised program name: '$prog', expected either 'lsd', 'lsf', 'lsl' or 'lsx'"
      ;;
  esac

  # Locate any additional command line switches for ls and accumulate them.
  # Likewise accumulate non-switches to the directories list.
  while [ $# -gt 0 ]
  do
    case "$1" in
      # FIXME: Handle switches that take arguments, eg --block-size
      # FIXME: Properly handle --almost-all, --ignore-backups, --format
      # FIXME:   and --ignore
      # FIXME: Properly handle --recursive
      -a | -A | --all | --almost-all)
        no_dots=0;
        ;;
      --version)
        report "version 1.2"
        exit 0
        ;;
      --help)
        case $type in
          d) report "a version of 'ls' that lists only directories" ;;
          l) report "a version of 'ls' that lists only links" ;;
          f) if [ "x$find_extras" = "x" ] ; then
               report "a version of 'ls' that lists only files" ;
             else
              report "a version of 'ls' that lists only executables";
             fi ;;
        esac
        exit 0
        ;;
      --)
        # A switch to say that all further items on the command line are
        # arguments and not switches.
        no_more_args=1 ;
        ;;
      -*)
        if [ "x$no_more_args" = "x1" ] ;
        then
          dirs[$num_dirs]="$1";
          let "num_dirs++"
        else
          # Check for a switch that just uses a single dash, not a double
          # dash.  This could actually be multiple switches combined into
          # one word, eg "lsd -alF".  In this case, scan for the -a switch.
          # XXX: FIXME: The use of =~ requires bash v3.0+.
          if [[ "x${1:1:1}" != "x-" && "x$1" =~ "x-.*a.*" ]] ;
          then
            no_dots=0;
          fi
          opts="$opts $1";
        fi
        ;;
      *)
        dirs[$num_dirs]="$1";
        let "num_dirs++"
        ;;
    esac
    shift
  done

  # Remember that we are counting from zero not one.
  if [ $num_dirs -gt 0 ] ;
  then
    let "num_dirs--"
  fi
}

list_things_in_dir ()
{
  local dir

  # Paranoia checks - the user should never encounter these.
  if test "x$1" = "x" ;
  then
    fail "list_things_in_dir called without an argument"
  fi

  if test "x$2" != "x" ;
  then
    fail "list_things_in_dir called with too many arguments"
  fi

  # Use quotes when accessing $dir in order to preserve
  # any spaces that might be in the directory name.
  dir="${dirs[$1]}";

  # Catch directory names that start with a dash - they
  # confuse pushd.
  if test "x${dir:0:1}" = "x-" ;
  then
    dir="./$dir"
  fi
 
  if [ -d "$dir" ]
  then
    if [ $num_dirs -gt 0 ]
    then
      echo "  $dir:"
    fi

    # Use pushd rather passing the directory name to find so that the
    # names that find passes on to xargs do not have any paths prepended.
    pushd "$dir" > /dev/null
    if [ $no_dots -ne 0 ] ; then
      find . -maxdepth 1 -type $type $find_extras -not -name ".*" -printf "%f\000" \
        | xargs --null --no-run-if-empty ls $opts -- ;
    else
      find . -maxdepth 1 -type $type $find_extras -printf "%f\000" \
        | xargs --null --no-run-if-empty ls $opts -- ;
    fi
    popd > /dev/null
  else
    report "directory '$dir' could not be found"
  fi
}

list_objects ()
{
  local i

  i=0;
  while [ $i -le $num_dirs ]
  do
    list_things_in_dir i
    let "i++"
  done
}

# Invoke main
main ${1+"$@"}

  1. この単純なBashスクリプトを使用して、自宅で両面ドキュメントを印刷します

    自宅にレーザープリンターがあります。このHewlettPackardLaserJet Pro CP1525nwカラープリンターは古いモデルですが、確実にカラーで印刷できる優れた主力製品です。数年前に、RaspberryPiをプリントサーバーとして使用してホームネットワークに配置しました。 LaserJetは、私のホームオフィスに追加された素晴らしい機能です。昨年会社を立ち上げて以来、この小さなレーザープリンターを利用して、クライアントの会議、ワークショップ、トレーニングセッション用の配布物やその他の資料を印刷してきました。 このプリンターの唯一の不満は、片面のみを印刷することです。両面

  2. 5 つの実用的な例を含む Bash スクリプト入門チュートリアル

    進行中の Unix Sed および Unix Awk シリーズと同様に、Bash スクリプトに関するいくつかの記事を投稿します。実用的な例ですべての bash スクリプト テクニックをカバーします。 シェルは、ユーザー コマンドを解釈するプログラムです。コマンドは、ユーザーが直接入力するか、シェル スクリプトと呼ばれるファイルから読み取るかのいずれかです。ユーザーからの入力を直接読み取る場合、シェルは対話型シェルとして呼び出されます。 シェルは、ファイルからコマンドを読み取って実行するときに、非対話型シェルとして呼び出されます。この場合、シェルはスクリプト ファイルの各行を上から下に読み取