bash: как l oop пройти через массив путей dir и удалить их определенные части - PullRequest
0 голосов
/ 24 февраля 2020

Массив longestPaths содержит пути к каталогам. Я хочу пройти через них oop и удалить их первые 3 директории. Например, учитывая следующие элементы массива в longestPaths:

/foo/bar/dir1/log/2020/02
/foo/bar/dir2/log/2020/01
/foo/bar/dir3/log/2019/12

Я хочу, чтобы другой массив содержал следующие значения после циклического перебора и изменения элементов в longestPaths:

/log/2020/02
/log/2020/01
/log/2019/12

Как я мог сделать это в bash (или в awk)? Спасибо

Ответы [ 2 ]

3 голосов
/ 24 февраля 2020

Solution1 с al oop:

Точное изменение записей массива longestPaths, как вы просили:

#!/bin/bash

# Populate longestPaths with sample data
declare -a longestPaths=(
  '/foo/bar/dir1/log/2020/02'
  '/foo/bar/dir2/log/2020/01'
  '/foo/bar/dir3/log/2019/12'
)

# Loop through indexes of the longestPaths array
for i in "${!longestPaths[@]}"; do
  # RegEx match entry at index to extract the short path
  [[ "${longestPaths[i]}" =~ \/log\/[[:digit:]]{4}\/[[:digit:]]{2}$ ]]

  # Replace the entry with its shortened version from the RegEx match
  longestPaths[i]="${BASH_REMATCH[0]}"
done

# Debug Print the modified longestPaths array
typeset -p longestPaths

Вывод:

declare -a longestPaths=([0]="/log/2020/02" [1]="/log/2020/01" [2]="/log/2019/12")

Solution2 с использованием Bash4 (с поддержкой mapfile):

Здесь это не l oop, а использование Gnu grep для обработки записей входного массива как записей с нулевым разделением.

#!/bin/bash

# Populate longestPaths with sample data
declare -a longestPaths=(
  '/foo/bar/dir1/log/2020/02'
  '/foo/bar/dir2/log/2020/01'
  '/foo/bar/dir3/log/2019/12'
)

# Declare a destination array of shortest paths
declare -a shortestPaths

# Map the null-delimited output of grep to the shortestPath array
mapfile -d '' shortestPaths < <(
  # Stream the null-delimited longestPaths array entries to grep
  printf '%s\0' "${longestPaths[@]}" |\
  grep \
    --null-data \
    --only-matching \
    --extended-regexp \
    --regexp='\/log\/[[:digit:]]{4}\/[[:digit:]]{2}$'
)

# shellcheck disable=SC2034 # Debug Print the shortestPaths array
typeset -p shortestPaths

Вывод:

declare -a shortestPaths=([0]="/log/2020/02" [1]="/log/2020/01" [2]="/log/2019/12")
1 голос
/ 24 февраля 2020

То, что у вас есть в качестве примера, это должно работать.

#!/usr/bin/env bash

shopt -s extglob

longestpath=(
    /foo/bar/dir1/log/2020/02
    /foo/bar/dir2/log/2020/01
    /foo/bar/dir3/log/2019/12
    /foo/bar/dir51/log/2019/12
    /foo/bar/dir10000/log/2019/12
    /foo/bar/dir99999999999999999999999999999/log/2019/12
)


printf '%s\n' "${longestpath[@]##*dir+([[:digit:]])}"

Вывод

/log/2020/02
/log/2020/01
/log/2019/12
/log/2019/12
/log/2019/12
/log/2019/12
  • Я добавил несколько длинных числительных c строк в элементах массива , просто чтобы показать, что независимо от того, сколько цифр после dir, глобус должен работать, как и ожидалось.
  • Как и то, что я сказал, если имя пути является постоянным, например, оно имеет dir, за которым следует число / di git Строки, которые должны работать.
...